Python __call__() 这是一个隐式类方法吗?

标签 python python-3.x metaclass class-method

我想在 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) 

并且代码运行完美。但是,__call__() 没有 self,也没有 @classmethod@staticmethod 声明。

但是,在 Python 数据模型中 https://docs.python.org/3/reference/datamodel.html#object.__call__ __call__() 方法在参数中有一个 self。

如果我传递 self,或者声明为 @staticmethod@classmethod,代码将不起作用。

谁能解释一下 __call__() 方法背后的语法逻辑。

最佳答案

将方法的第一个参数命名为 clsself 只是一种约定__call__ 方法确实 有一个 self 参数,只是它在这里被命名 cls。那是因为对于元类,方法绑定(bind)到类对象,名称反射(reflect)了这一点。

相同的约定适用于@classmethod 方法;由于 classmethod 对象的绑定(bind)方式的性质,第一个参数始终是一个类,因此将第一个参数命名为 cls 是有意义的。

但是您可以随意为第一个参数命名。使类方法或常规方法或元类型上的方法起作用的不是名称。使用 selfcls 所做的只是记录这是什么类型的对象,让其他开发人员更容易在脑海中跟踪正在发生的事情.

所以不,这不是隐式类方法。第一个参数未绑定(bind)到 Singleton 元类对象,它绑定(bind)到被调用的类。这是有道理的,因为该类对象是 Singleton 元类型的一个实例。

如果您想深入了解绑定(bind) 的工作原理(导致传入第一个参数的过程,无论名称如何),您可以阅读 Descriptor HOWTO . TLDR:函数、propertyclassmethodstaticmethod 对象都是描述符,无论何时您将它们作为属性访问在支持对象(例如实例或类)上,它们是绑定(bind)的,通常会导致返回一个不同对象作为结果,在调用时将绑定(bind)对象传递给实际函数。 p>

关于Python __call__() 这是一个隐式类方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44704461/

相关文章:

python - 使用 python ('NoneType' 对象进行网页抓取没有属性 'get_text' )

python - 使用 iloc 创建虚拟变量时出现 TypeError

Python Tkinter 小窗口在主窗口之前弹出

无时间漂移的Python异步生成器函数

使用大量参数和默认值初始化对象的 Pythonic 方法

python-3.x - PythonPDF : FileNotFoundError: [WinError 2] The system cannot find the file specified

python - 将数据描述符传递给函数

Python动态属性和mypy

python - 元类是否首先实例化类的属性?

python-3.x - 防止抽象类的实例化