我正在关注此link并尝试制作单身课程。但是,考虑参数(在启动类时传递),以便在参数相同时返回相同的对象。
因此,我不想将类名/类引用存储为dict
键,而是希望将传递的参数存储为dict
中的键。但是,也可能存在不可用的参数(例如dict
,set
本身)。
存储类参数和类对象映射的最佳方法是什么?这样我就可以返回与参数对应的对象。
非常感谢。
EDIT-1 : 多一点解释。假设有如下课程
class A:
__metaclass__ == Singleton
def __init__(arg1, arg2):
pass
现在,A(1,2)
应始终返回相同的对象。但是,它应该与A(3,4)
我认为,这些论点很大程度上定义了一个阶级的功能。假设该类是否要建立redis
连接。我可能想要使用diff redis
hosts作为参数创建2个单例对象,但底层的类/代码可能很常见。
答案 0 :(得分:0)
正如我和评论中已经提到的那样,在依赖不可缓存的值进行缓存或记忆时,存在一些可能性。因此,如果您仍想要这样做,则以下示例不会隐藏__new__
或__init__
方法中的memoization。 (自我记忆类会有危险,因为记忆标准可能被你无法控制的代码所欺骗。)
相反,我提供了函数memoize
,它返回一个类的memoizing工厂函数。由于没有通用的方法来告诉非可扩展的参数,如果它们将导致一个等效于已存在的isntance的实例,则必须明确提供memoization语义。这是通过将keyfunc
函数传递给memoize
来实现的。 keyfunc
使用与类“__init__
方法相同的参数,并返回一个哈希键,其相等关系(__eq__
)决定了memoization。
正确使用memoization是使用代码的责任(提供合理的keyfunc
并使用工厂),因为要记忆的类不会被修改,仍然可以正常实例化。
def memoize(cls, keyfunc):
memoized_instances = {}
def factory(*args, **kwargs):
key = keyfunc(*args, **kwargs)
if key in memoized_instances:
return memoized_instances[key]
instance = cls(*args, **kwargs)
memoized_instances[key] = instance
return instance
return factory
class MemoTest1(object):
def __init__(self, value):
self.value = value
factory1 = memoize(MemoTest1, lambda value : value)
class MemoTest2(MemoTest1):
def __init__(self, value, foo):
MemoTest1.__init__(self, value)
self.foo = foo
factory2 = memoize(MemoTest2, lambda value, foo : (value, frozenset(foo)))
m11 = factory1('test')
m12 = factory1('test')
assert m11 is m12
m21 = factory2('test', [1, 2])
lst = [1, 2]
m22 = factory2('test', lst)
lst.append(3)
m23 = factory2('test', lst)
assert m21 is m22
assert m21 is not m23
我只将MemoTest2
作为MemoTest1
的子类包含在内,以表明使用常规类继承没有任何魔力。