class MyType(type):
def __init__(self, what, bases=None, dict=None):
print('call myType.__init__()') #语句 1
super().__init__(what, bases, dict)
def __new__(cls, name, bases, attrs):
print("call MyType.__new__()") #语句 2
return type.__new__(cls, name, bases, attrs)
def __call__(self, *args, **kwargs):
print("MyType.__call__")
class Foo(object, metaclass=MyType):
def __init__(self, name=None):
self.name = name
print("Foo self.name=", self.name)
def __new__(cls, *args, **kwargs):
print("Foo.__new__ cls=", cls)
return(object.__new__(cls, *args, **kwargs))
def __call__(self, cls):
print("Foo.__call__ cls=", cls)
if name == 'main':
print("---------test---------") #语句 3
obj=Foo() #语句 4
上面代码在 PYTHON3.6 中输出如下:
call MyType.new() #语句 2 的输出
call myType.init() #语句 1 的输出
---------test---------
MyType.call #语句 4 的输出
请问,为何语句 4 “ obj=Foo()” 会导致__call__方法的执行? 我看了这篇博文 python.jobbole.com/83747/ 博文的“ 5.call”小节写了这段话:“注:构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()”
看了这段话后再结合上面这个程序,我就觉得有问题,obj=Foo()这个语句应该是博文中的 对象=类名() 这个形式,所以不应该调用 Foo.call()方法才对啊? 关于这个观点,我还有一个例子可以说明,比如下面这段代码和对应的输出,请注意语句 1 就是一个把对象实例化的语句,这个语句并没有调用类的__call__()方法,所以两个例子出现了矛盾,同样是类的实例化,上面的程序调用了类的 call 方法,下面的却没有:
class Deco:
def __init__(self,func):
self.func=func
print("__init__执行完毕。func=",self.func)
def __call__(self,*arg,**arg2):
print("开始执行__call__。")
self.func('abc')
print(self,arg,arg2)
class MyCls():
@Deco
def myFunc(self):
print('this is my work arg is %s'%self)
mycls=MyCls()
deco=Deco(mycls.myFunc)
代码输出如下: __init__执行完毕。func= <function MyCls.myFunc at 0x01C49AE0>
__init__执行完毕。func= <main.Deco object at 0x01C4B190>
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.