请教类的实例化的问题

2017-07-17 20:13:50 +08:00
 saximi
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 的输出


我的问题如下:
1、当 PYTHON 加载模块的时候,是否就会自动执行类定义中的 __init__和__new__方法,以此实现为类分配内存的目的?
2、为何语句 4 “ obj=Foo()” 会导致__call__方法的执行?
我看了一些博文,都提到“对象=类名()”这样的语句是不应该导致__call__执行的,只有“对象()”以及“类名()()”这两种语句才会触发__call__,
上面语句 4 的输出是怎么回事呢?

感谢指点!
1559 次点击
所在节点    Python
4 条回复
saximi
2017-07-17 20:16:37 +08:00
顺便问一下,为何我在外面编辑好的代码包含了缩进,一贴到论坛里就体现不出缩进了?
bravecarrot
2017-07-18 01:18:14 +08:00
附加问题:你需要使用 markdown,代码块儿是''' 1⃣️那个键位。
1. 先调用__new__。但是很少有人这么写,因为一般都用不到。参见 stackoverflow 上关于 new 的问题。然后调用 init。是不是分配内存,我没研究过,不妄言
2.obj=Foo()==Foo.__call__()
NoAnyLove
2017-07-18 10:29:51 +08:00
要用 Markdown 格式包围代码才能保证缩进,而且仅对发帖有效,回帖不支持 Markdown
saximi
2017-07-18 21:37:22 +08:00
@bravecarrot 感谢,但是我越发糊涂了。
我看了这篇博文 http://python.jobbole.com/83747/
博文的“ 5.__call__”小节写了这段话:“注:构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()”

就是因为看了这段话,结合这个程序,我才觉得有问题,obj=Foo()这个语句应该是博文中的 对象=类名() 这个形式,所以不应该调用 Foo.__call__()方法才对啊?
关于这个观点,我还有一个例子可以说明,比如下面这段代码和对应的输出,请注意语句 1 就是一个把对象实例化的语句,这个语句并没有调用类的__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) #语句 1

代码输出如下:
__init__执行完毕。func= <function MyCls.myFunc at 0x01C49AE0>
__init__执行完毕。func= <__main__.Deco object at 0x01C4B190>

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/375985

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX