【发布时间】:2017-04-30 12:48:29
【问题描述】:
我有这个代码:
class Singleton(type):
def __call__(cls,*args,**kwargs):
if cls.created is None :
print('called')
cls.created = super().__call__(*args,**kwargs)
return cls.created
else:
return cls.created
def __new__(cls,name,base,attr,**kwargs):
return super().__new__(cls,name,base,attr,**kwargs)
class OnlyOne(metaclass=Singleton):
created = None
def __init__(self,val):
self.val = val
class OnlyOneTwo(OnlyOne):
pass
k = OnlyOne(1)
a = OnlyOneTwo(2)
print(a.val)
print(k.val)
print('a.created: {0} - b.created: {1}'.format(id(a.created),id(k.created)))
我是 Python 3 的新手,所以我决定做一些小实验,并尝试使用 Python 的元类。
在这里,我尝试创建一个元类,在设置时将类限制为单个实例。
我不确定这是否有效,但每当我尝试这样做时:
k = OnlyOne(1)
a = OnlyOneTwo(2)
输出将是:
called
1
1
这意味着 OnlyOneTwo 没有设置,但是当我尝试这样做时:
a = OnlyOneTwo(2)
k = OnlyOne(1)
输出将是:
called
called
2
1
有人可以帮我追溯吗?我有点困惑,但这是我最初的问题/想法:
OnlyOneTwo的created属性与OnlyOne的属性相同吗?因为我通过id()得到不同的结果,具体取决于我首先定义的结果。如果是OnlyOneTwo,则不同,但如果是OnlyOne,则相同。如果我要运行
a = OnlyOneTwo(2) print(OnlyOne.created),为什么created仍然是None?
【问题讨论】:
-
可以先添加
print('__new__\tcls:{}\n\tname:{}\n\tbase:{}\n\tattr:{}'.format(cls,name,base,attr))作为__new__的第一行。
标签: python inheritance namespaces metaclass