【发布时间】:2014-12-28 05:57:09
【问题描述】:
我有几个类需要执行以下操作:
当构造函数被调用时,如果一个相等的对象(也就是一个具有相同 id 的对象)已经存在,则返回那个对象。否则,创建一个新实例。 基本上,
>>> cls(id=1) is cls(id=1)
True
为了实现这一点,我编写了一个类装饰器,如下所示:
class Singleton(object):
def __init__(self, cls):
self.__dict__.update({'instances': {},
'cls': cls})
def __call__(self, id, *args, **kwargs):
try:
return self.instances[id]
except KeyError:
instance= self.cls(id, *args, **kwargs)
self.instances[id]= instance
return instance
def __getattr__(self, attr):
return getattr(self.cls, attr)
def __setattr__(self, attr, value):
setattr(self.cls, attr, value)
这是我想要的,但是:
@Singleton
class c(object):
def __init__(self, id):
self.id= id
o= c(1)
isinstance(o, c) # returns False
我该如何解决这个问题?我找到了related question,但我似乎无法让这些解决方案适应我的用例。
我知道有人会要求我发布一些不起作用的代码,所以你去吧:
def Singleton(cls):
instances= {}
class single(cls):
def __new__(self, id, *args, **kwargs):
try:
return instances[id]
except KeyError:
instance= cls(id, *args, **kwargs)
instances[id]= instance
return instance
return single
# problem: isinstance(c(1), c) -> False
def Singleton(cls):
instances= {}
def call(id, *args, **kwargs):
try:
return instances[id]
except KeyError:
instance= cls(id, *args, **kwargs)
instances[id]= instance
return instance
return call
# problem: isinstance(c(1), c) -> TypeError
【问题讨论】:
-
我自己并没有真正研究过它,但是有一篇关于“通用装饰器”的 10 部分博客文章非常好。 blog.dscpl.com.au/2014/01/how-you-implemented-your-python.html 是第一个。此处引用的集合:github.com/GrahamDumpleton/wrapt/tree/master/blog
-
致那些投反对票的人:我很感激您的评论。如果你不告诉我我做错了什么,我无法提出更好的问题。
-
@abarnert:为什么不试试呢? :) 它将产生一个
RuntimeError: maximum recursion depth exceeded,因为__setattr__试图检索self.cls。 -
@Rawing:啊,对。通常我会通过让
__setattr__变得聪明来处理这个问题,而不是背着它,但我想这也可以。 -
@Rawing 在新式类中它是recommended to use 类似于
object.__setattr__(self, 'instances', {});object.__setattr__(self, 'cls', cls),因为这尊重描述符协议。
标签: python class python-2.7 python-decorators