Ara*_*Fey 4 python class python-2.7 python-decorators
我有几个类需要执行以下操作:
调用构造函数时,如果已存在相等的对象(也称为具有相同id的对象),则返回该对象.否则,创建一个新实例.基本上,
>>> cls(id=1) is cls(id=1)
True
Run Code Online (Sandbox Code Playgroud)
为此,我编写了一个类装饰器,如下所示:
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)
Run Code Online (Sandbox Code Playgroud)
这样做我想要的,但是:
@Singleton
class c(object):
def __init__(self, id):
self.id= id
o= c(1)
isinstance(o, c) # returns False
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?我发现了一个相关的问题,但我似乎无法将这些解决方案改编为我的用例.
我知道有人要我发布一些不起作用的代码,所以你去了:
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
Run Code Online (Sandbox Code Playgroud)
您可以__instancecheck__在装饰器类中添加自定义挂钩:
def __instancecheck__(self, other):
return isinstance(other, self.cls)
Run Code Online (Sandbox Code Playgroud)