繁体   English   中英

如何从静态方法创建类的实例?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM