Jee*_*eva 2 python metaclass class-method python-3.x
我想在python中实现一个单例模式,我喜欢http://www.python-course.eu/python3_metaclasses.php中描述的模式.
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class SingletonClass(metaclass=Singleton):
pass
class RegularClass():
pass
x = SingletonClass()
y = SingletonClass()
print(x == y)
x = RegularClass()
y = RegularClass()
print(x == y)
Run Code Online (Sandbox Code Playgroud)
代码工作得很完美.但是,__call__()没有self,它也没有@classmethod或@staticmethod声明.
但是,在Python数据模型https://docs.python.org/3/reference/datamodel.html#object.__call__中,该__call__()方法在参数中有一个self.
如果我通过self或声明为@staticmethod或,则代码不起作用@classmethod.
有人可以解释一下该__call__()方法背后的语法逻辑.
命名方法的第一个参数cls或者self是只是一个约定.该__call__方法确实有一个自我参数,只有它在这里命名 cls.那是因为对于元类,该方法绑定到一个类对象,名称反映了这一点.
同样的惯例适用于@classmethod方法; 由于classmethod对象如何绑定的性质,第一个参数总是一个类,所以命名第一个参数是有意义的cls.
但你可以自由地将第一个参数命名为其他任何东西.它不是使类方法或常规方法或方法在元类型上工作的名称.所有使用self或cls做的都是记录这是什么类型的对象,使其他开发人员更容易在心理上跟踪正在发生的事情.
所以不,这不是一个隐式的类方法.第一个参数没有绑定到Singleton元类对象,它被绑定到被调用的类.这是有道理的,因为该类对象是元类型的实例Singleton.
如果你想深入了解绑定是如何工作的(导致第一个参数传入的过程,无论名称如何),你可以阅读描述符HOWTO.TLDR:函数property,classmethod和staticmethod对象都是描述符,每当你访问它们作为属性支撑物上的,如实例或类,他们必然,往往导致不同的对象返回的结果,调用时将绑定对象传递给实际函数.
| 归档时间: |
|
| 查看次数: |
1652 次 |
| 最近记录: |