美文网首页
python学习:神奇的__call__函数

python学习:神奇的__call__函数

作者: 倔犟的贝壳 | 来源:发表于2021-11-07 09:19 被阅读0次

    在最近的学习中发现,装饰器与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的时候随时查看。

    相关文章

      网友评论

          本文标题:python学习:神奇的__call__函数

          本文链接:https://www.haomeiwen.com/subject/fhejzltx.html