[英]How to create instances of a class from a static method?
这是我的问题。 我创建了一个非常繁重的只读类,使用静态的“工厂”方法进行了许多数据库调用。 此方法的目的是,如果已经存在相同对象(相同类型,相同初始化参数)的相同实例,则通过查看已创建对象的池来避免杀死数据库。
如果找到了什么,该方法将返回它。 没问题。 但是,如果没有,如何用继承的方式创建对象的实例?
>>> class A(Object):
>>> @classmethod
>>> def get_cached_obj(self, some_identifier):
>>> # Should do something like `return A(idenfier)`, but in a way that works
>>> class B(A):
>>> pass
>>> A.get_cached_obj('foo') # Should do the same as A('foo')
>>> A().get_cached_obj('foo') # Should do the same as A('foo')
>>> B.get_cached_obj('bar') # Should do the same as B('bar')
>>> B().get_cached_obj('bar') # Should do the same as B('bar')
谢谢。
import weakref
class A(object):
_get_obj_cache = weakref.WeakValueDictionary()
@classmethod
def get_obj(cls, identifier):
cache = cls._get_obj_cache
obj = cache.get((cls, identifier))
if obj is None:
obj = cache[(cls, identifier)] = cls(identifier)
return obj
class B(A):
pass
因为使用了WeakValueDictionary,所以只要您有其他引用,这些对象就将保持高速缓存,并且可以多次调用SomeClass.get_obj(identifier)来获取同一对象。 如果我对您的理解正确,那么正是cls(identifier)
可以访问数据库以及您不希望调用的内容,因为您知道对象是不可变的。
如果即使对象不再在其他地方引用也要保留在缓存中,则将WeakValueDictionary更改为普通字典。
这要求标识符适合于dict键,如果它是示例代码中的字符串,那么它就是。
一种通常的方法是这种方法。
class SomeClass( object ):
# Something that is precious and needs to be pooled.
class SomeClassPool( object ):
def __init__( self ):
self.pool= [ SomeClass() ]
def getInstance( self ):
if len(self.pool) == 0:
self.pool.append( SomeClass() )
# maybe allocate several, depends on the costs
return self.pool.pop()
def release( self, anInstance ):
self.pool.append( anInstance )
我们将池与被池化的对象分开。 他们彼此无关。
您可以将所有想要合并的对象子类化。
您可以独立地更改池化策略,而无需破坏或重新测试要池化的对象。
扩展S.Lott的评论:
“我想每次都返回正确的实例,而不将其从池中删除”。 您的意思是您想要对象字典? -S.Lott
the_cache = {}
def get_obj(cls, identifier):
key = (cls, identifier)
if key not in the_cache:
the_cache[key] = cls(identifier)
return the_cache[key]
要么
def get_obj(cls, identifier):
key = (cls, identifier)
try:
return the_cache[key]
except KeyError:
the_cache[key] = cls(identifier)
return the_cache[key]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.