stacklens / dusai-blog

杜赛的博客的评论区。详情见 Issue。
2 stars 0 forks source link

article/150/ #92

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

Python魔法方法漫游指南:可调用和槽 - 杜赛的博客

https://www.dusaiphoto.com/article/150/

frostming commented 3 years ago

函数本身也是可调用对象,所以函数也有 __call__(), 进一步 __call__ 也是可调用对象,所以 __call__ 也有 __call__():

def foo():
    return 42

foo.__call__.__call__.__call__.__call__()
# 42

接下来想到,类的实例化也是Foo(),那么类是不是也有 __call__() ?答案是肯定的:

class Foo:
    def __init__(self, x):
        print("initialized", x)
        self.x = x
Foo.__call__(42)
# initialized 42

但当Foo定义了__call__() 方法,这就不行了

class Foo:
    def __init__(self, x):
        print("initialized", x)
        self.x = x
    def __call__(self):
        return self.x
Foo.__call__(42)
# AttributeError: 'int' object has no attribute 'x'

这时,可以退回用基类的__call__方法,一个类,它作为实例,它的基类是type

type.__call__(Foo, 42)
# initialized 42

注意这里type.__call__() 不等于 type(),可以试试 type(Foo, 42)

stacklens commented 3 years ago

@frostming 啊,都没想得这么全面,受教了明佬👍👍👍细节全都说到了