Subclassing class 实现单例思想 metaclass
Subclassing a class that implements singleton thought metaclass
我有这个代码:
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 的 metaclasses。
在这里,我尝试制作一个元class,在设置时将 class 严格限制为单个实例。
我不确定这是否有效,但每当我尝试这样做时:
k = OnlyOne(1)
a = OnlyOneTwo(2)
输出将是:
called
1
1
这意味着 OnlyOneTwo
没有设置但是当我尝试这样做时:
a = OnlyOneTwo(2)
k = OnlyOne(1)
输出将是:
called
called
2
1
有人可以帮我追溯吗?我有点困惑,但这是我的初始 questions/thoughts:
OnlyOneTwo
的created
属性和OnlyOne
的一样吗?因为我通过 id()
得到不同的结果,具体取决于我首先定义的结果。如果先OnlyOneTwo
就不一样,如果先OnlyOne
就一样了
我怎么会created
还是None
运行a = OnlyOneTwo(2)
print(OnlyOne.created)
?
我会试一试。我认为症状是由于 __call__
.
中的分配 cls.created = ...
当 class objects 首次创建时 OnlyOneTwo.created
指向 OnlyOne.created
。它们都具有相同的 id
,这与 None
.
相同
>>> id(None)
506773144
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 506773144)
如果先创建OnlyOne
的实例,实例会被分配给OnlyOne.created
(它不再指向 None
)但是 OnlyOneTwo.created
仍然指向 OnlyOne.created
- 它们仍然是同一件事,因此当调用 OnlyOneTwo
时,执行条件的 else 子句。
>>> a = OnlyOne('a')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54522152, 54522152)
>>> z = OnlyOneTwo('z')
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54522152, 54522152)
>>> id(a)
54522152
当您首先创建 OnlyOneTwo
的实例时,该实例被分配给 OnlyOneTwo.created
,它不再 指向 OnlyOne.created
。 OnlyOne.created
仍然 指向 None
.
>>> id(None)
506773144
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 506773144)
>>> z = OnlyOneTwo('z')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 54837544)
>>> id(z)
54837544
现在,当您创建 OnlyOne
的实例时,if 条件为 True 并且实例被分配给 OnlyOne.created
>>> a = OnlyOne('a')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54352752, 54837544)
>>> id(a)
54352752
我经常发现自己re-readingBinding of Names and Resolution of Names - also A Word About Names and Objects and Python Scopes and Namespaces
我感觉我没有真正解释过这个机制——我不是很理解child class属性指向基本class属性——它不同于a = b = None
。
也许:
- 最初 child class 实际上 没有 属性, 指向 机制是继承是如何实现的,因为它 没有 属性,所以在其 parent(s).
中搜索该属性
- 即使 parent class 属性 改变了 实例化, child class 仍然没有 具有 属性并必须搜索它,它找到了 new 东西。
- 如果 child class 首先实例化元 class 中的赋值 将 属性赋予 child class - 现在它 有 它不需要搜索它。
Re-reading 文档中 Standard Type Hierarchy 的自定义 类 部分触发了那个大脑转储。
我觉得我以前来过这里,甚至可能在 SO。希望我这次记住了,不用再想了。
如果你想修复你的单身人士,如果你搜索它们,有很多选择。使用 metaclass 似乎实例保存在 metaclass 中,而不是 class 本身。 Creating a singleton in Python,SO Q&A,是一个好的开始。
我有这个代码:
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 的 metaclasses。
在这里,我尝试制作一个元class,在设置时将 class 严格限制为单个实例。
我不确定这是否有效,但每当我尝试这样做时:
k = OnlyOne(1)
a = OnlyOneTwo(2)
输出将是:
called
1
1
这意味着 OnlyOneTwo
没有设置但是当我尝试这样做时:
a = OnlyOneTwo(2)
k = OnlyOne(1)
输出将是:
called
called
2
1
有人可以帮我追溯吗?我有点困惑,但这是我的初始 questions/thoughts:
OnlyOneTwo
的created
属性和OnlyOne
的一样吗?因为我通过id()
得到不同的结果,具体取决于我首先定义的结果。如果先OnlyOneTwo
就不一样,如果先OnlyOne
就一样了我怎么会
created
还是None
运行a = OnlyOneTwo(2) print(OnlyOne.created)
?
我会试一试。我认为症状是由于 __call__
.
cls.created = ...
当 class objects 首次创建时 OnlyOneTwo.created
指向 OnlyOne.created
。它们都具有相同的 id
,这与 None
.
>>> id(None)
506773144
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 506773144)
如果先创建OnlyOne
的实例,实例会被分配给OnlyOne.created
(它不再指向 None
)但是 OnlyOneTwo.created
仍然指向 OnlyOne.created
- 它们仍然是同一件事,因此当调用 OnlyOneTwo
时,执行条件的 else 子句。
>>> a = OnlyOne('a')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54522152, 54522152)
>>> z = OnlyOneTwo('z')
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54522152, 54522152)
>>> id(a)
54522152
当您首先创建 OnlyOneTwo
的实例时,该实例被分配给 OnlyOneTwo.created
,它不再 指向 OnlyOne.created
。 OnlyOne.created
仍然 指向 None
.
>>> id(None)
506773144
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 506773144)
>>> z = OnlyOneTwo('z')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(506773144, 54837544)
>>> id(z)
54837544
现在,当您创建 OnlyOne
的实例时,if 条件为 True 并且实例被分配给 OnlyOne.created
>>> a = OnlyOne('a')
called
>>> id(OnlyOne.created), id(OnlyOneTwo.created)
(54352752, 54837544)
>>> id(a)
54352752
我经常发现自己re-readingBinding of Names and Resolution of Names - also A Word About Names and Objects and Python Scopes and Namespaces
我感觉我没有真正解释过这个机制——我不是很理解child class属性指向基本class属性——它不同于a = b = None
。
也许:
- 最初 child class 实际上 没有 属性, 指向 机制是继承是如何实现的,因为它 没有 属性,所以在其 parent(s). 中搜索该属性
- 即使 parent class 属性 改变了 实例化, child class 仍然没有 具有 属性并必须搜索它,它找到了 new 东西。
- 如果 child class 首先实例化元 class 中的赋值 将 属性赋予 child class - 现在它 有 它不需要搜索它。
Re-reading 文档中 Standard Type Hierarchy 的自定义 类 部分触发了那个大脑转储。
我觉得我以前来过这里,甚至可能在 SO。希望我这次记住了,不用再想了。
如果你想修复你的单身人士,如果你搜索它们,有很多选择。使用 metaclass 似乎实例保存在 metaclass 中,而不是 class 本身。 Creating a singleton in Python,SO Q&A,是一个好的开始。