python学习:神奇的__call__函数

在最近的学习中发现,装饰器与metaclass都离不开__call__。python中的__call__函数到底是什么呢?

__call__是python内置的特殊函数,在type类中定义。它的作用是使自己的实例像函数一样去调用(Call self as a function. )下面是我找到的它的定义

class type(object):
    """
    type(object_or_name, bases, dict)
    type(object) -> the object's type
    type(name, bases, dict) -> a new type
    """
    def mro(self, *args, **kwargs): # real signature unknown
        """ Return a type's method resolution order. """
        pass

    def __call__(self, *args, **kwargs): # real signature unknown
        """ Call self as a function. """
        pass

所谓说的Call self as a function.,看下面的例子

class MyClass:
    def __init__(self):
        print("__init__")
    def __call__(self,data):
        print("__call__")
        self.data = data
        
instance = MyClass()
instance(2)
print(instance)
print(instance.data)

#######输出
__init__
__call__
<__main__.MyClass object at 0x7fb4b64baa90>
2

看到了吗?instance实例,能够像函数一样使用,而它调用的就是__call__()函数。我们所有自定义的python类都是type的实例,通过重载__call__()函数实现。
我们正常创建一个类如下:

class MyClass:
    def __init__(self,data):
        self.data = data
        
def create_class_nomal():
    instance = MyClass(1)
    print(MyClass)
    print(instance)
    print(instance.data)
create_class_nomal()
#输出:
<class '__main__.MyClass'>
<__main__.MyClass object at 0x7fb4b6152b50>
1

但上面的type类也告诉我们了,我们也可以用type创建一个类。如下:

def create_class_by_type():
    MyClass = type("MyClass",(),{'data':1})
    instance = MyClass()
    print(MyClass)
    print(instance)
    print(instance.data)
create_class_by_type()   

#### 输出
<class '__main__.MyClass'>
<__main__.MyClass object at 0x7fb4b8c162e0>
1

当我们定义一个类时,实际上是调用了:

type(name, bases, dict) -> a new type
name:类名
bases:superclass
dict:成员变量的name与value

也就是__call__()函数的重载。接着它会进一步调用__init__()和__new__()

好了,__call__()函数暂时记录于此,方便装饰器和metaclass的时候随时查看。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容