请大家指点

2017-07-10 19:50:33 +08:00
 saximi
class MyType(type):
def __init__(self, what, bases=None, dict=None):
print('call myType.__init__()')
print("class name:"+what)
print("class bases:"+str(bases))
print("class attributions:"+str(dict))
super().__init__(what, bases, dict)
def __new__(cls, name, bases, attrs):
print("call MyType.__new__()")
return type.__new__(cls, name, bases, attrs)
class Foo(object):
__metaclass__ = MyType #语句 1
def __init__(self, name=None):
self.name = name
print("Foo.__init__ self=", self)
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)
print("Foo.__call__ self=", self)
def func(self):
print('function is there')
class studen(Foo):
print("studen(Foo)") #语句 2
def __init__(self, name=None):
print("studen.__init__ self=", self)

class Foo2(object):
"""docstring for Foo2"""
def __init__(self):
print('Foo2.__init__ self.__class__=', self.__class__)
print("Foo2.__init__ type(self)=", type(self))

if __name__ == '__main__':
print("---------test1---------") #语句 3
obj2=Foo() #语句 4
print("---------test2---------")
print("test2 type=", type(studen()))
print("---------test3---------")
print("test3 type=", type(Foo2()))

上面这段代码的输出如下:
studen(Foo)
---------test1---------
Foo.__new__ cls=
Foo.__init__ self= <__main__.Foo object at 0x01C2A270>
Foo self.name= None
---------test2---------
Foo.__new__ cls=
studen.__init__ self= <__main__.studen object at 0x01C2A350>
test2 type=
---------test3---------
Foo2 self.__class__=
Foo2 type(self)=
test3 type=



我的问题如下:
1、为何语句 2 会在语句 3 之前先执行了?是不是因为类定义中的不在__new__()、__init__()和__call__()的方法之内的语句都会在模块被加载的时候立即执行?
2、在语句 1 中,我已经指定 Foo 类要由 MyType 类来实例化创建,为何执行语句 4 的时候,类 MyType 定义中的__new__()和__init__()方法都没有被首先执行?

恳请指点,感谢!
1515 次点击
所在节点    Python
4 条回复
zhusimaji
2017-07-11 16:57:47 +08:00
给楼主贴上我自己 python2 改造后的代码
https://gist.github.com/zhusimaji/31fe157b62703923bf6177f05f0fdbac
依次回答楼主的问题
( 1 )类被倒入加载时,print 没有放在类定义的函数中是会被运行打印
( 2 )语句 4 -> metaclass 是__new__和__init__都是先运行,没有任何问题
zhusimaji
2017-07-11 16:59:47 +08:00
这个可能与 python3 有关,建议楼主看下 python 3 关于 type 的说明
saximi
2017-07-12 20:12:31 +08:00
@zhusimaji 非常感谢啊!
但是关于第二个问题的回答“语句 4 -> metaclass 是__new__和__init__都是先运行,没有任何问题”我还是没明白。
在语句 1 中已经指定 Foo 类要由 MyType 类来实例化创建,所以我觉得执行“ obj2=Foo()”这个语句时,应该就是实例化了一个类 Foo 的对象并赋值给 obj2,但是要根据 MyType 的定义来实例化。
这时应该去执行 MyType 定义中的__new__和__init__,而不是去执行 Foo 定义中的__new__和__init__。我这个理解错在哪里呢?

另外,您修改后的代码在 PYTHON2 下运行,在类被加载时会先去执行 MyType 中的__new__和__init__,然后再执行语句 3。 但是为何在 PYTHON3 下,类被加载时不会执行 MyType 中的语句,而是直接就执行语句 3 呢?
saximi
2017-07-15 14:47:56 +08:00
自己再顶一下,上面说的遗留的问题,还请大家不吝赐教,感谢!

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

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

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

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

© 2021 V2EX