python 对象创建过程的详细信息是什么?
What is the detail of python object creation process?
当我学习 __int__
、__new__
、__call__
和 python 的 metaclass 时,我对以下代码感到困惑:
class MyMeta(type):
def __init__(cls, name, bases, attr):
print 'enter MyMeta'
super(MyMeta, cls).__init__(name, bases, attr)
print 'leave MyMeta'
def __call__(cls, *args, **kwargs):
print 'enter MyMeta __call__'
instance = super(MyMeta, cls).__call__(*args, **kwargs)
print 'leave MyMeta __call__'
return instance
class MyObj(object):
__metaclass__ = MyMeta
def __init__(self, *args, **kwargs):
print 'enter MyObj __init__'
super(MyObj, self).__init__()
self.aaa = args[0]
self.kw = kwargs
print self.aaa, self.kw
print 'leave MyObj __init__'
def __new__(cls, *args, **kwargs):
print 'enter MyObj __new__'
instance = super(MyObj, cls).__new__(cls, *args, **kwargs)
print 'leave MyObj __new__'
return instance
obj = MyObj(123, k=456)
输出为:
enter MyMeta #L1
leave MyMeta #L2
enter MyMeta __call__ #L3
enter MyObj __new__ #L4
leave MyObj __new__ #L5
enter MyObj __init__ #L6
123 {'k': 456} #L7
leave MyObj __init__ #L8
leave MyMeta __call__ #L9
我的问题是:
1、创建对象时,流程是__call__
的metacall,然后是__new__
和__init__
的class,对吗?
这是我从日志中看到的,有什么我遗漏的吗?
1) 正确 - 大部分 - 元类的 __call__
(在这种情况下,metaclass
的超类的 __call__
即 type
)调用来自实例的 __init__
和 __new__
。
2) 通过省略传递给元类的超级 __call__
,您将 kwargs 扔给了实例的 __init__
和 __new__
。元类'__call__
负责调用实例的__new__
和__init__
.
附带说明:使用 Python 3 - 深入学习 Python 2.x 过去的工作方式没有意义 - 自上次以来已经七年了发布一个 Python 2 和 3 年到它的末尾。 (虽然你正在调查的过程没有改变,但元类的声明方式 - 但给我的 "auf, this is old" 是带参数的 super
)
当我学习 __int__
、__new__
、__call__
和 python 的 metaclass 时,我对以下代码感到困惑:
class MyMeta(type):
def __init__(cls, name, bases, attr):
print 'enter MyMeta'
super(MyMeta, cls).__init__(name, bases, attr)
print 'leave MyMeta'
def __call__(cls, *args, **kwargs):
print 'enter MyMeta __call__'
instance = super(MyMeta, cls).__call__(*args, **kwargs)
print 'leave MyMeta __call__'
return instance
class MyObj(object):
__metaclass__ = MyMeta
def __init__(self, *args, **kwargs):
print 'enter MyObj __init__'
super(MyObj, self).__init__()
self.aaa = args[0]
self.kw = kwargs
print self.aaa, self.kw
print 'leave MyObj __init__'
def __new__(cls, *args, **kwargs):
print 'enter MyObj __new__'
instance = super(MyObj, cls).__new__(cls, *args, **kwargs)
print 'leave MyObj __new__'
return instance
obj = MyObj(123, k=456)
输出为:
enter MyMeta #L1
leave MyMeta #L2
enter MyMeta __call__ #L3
enter MyObj __new__ #L4
leave MyObj __new__ #L5
enter MyObj __init__ #L6
123 {'k': 456} #L7
leave MyObj __init__ #L8
leave MyMeta __call__ #L9
我的问题是:
1、创建对象时,流程是__call__
的metacall,然后是__new__
和__init__
的class,对吗?
这是我从日志中看到的,有什么我遗漏的吗?
1) 正确 - 大部分 - 元类的 __call__
(在这种情况下,metaclass
的超类的 __call__
即 type
)调用来自实例的 __init__
和 __new__
。
2) 通过省略传递给元类的超级 __call__
,您将 kwargs 扔给了实例的 __init__
和 __new__
。元类'__call__
负责调用实例的__new__
和__init__
.
附带说明:使用 Python 3 - 深入学习 Python 2.x 过去的工作方式没有意义 - 自上次以来已经七年了发布一个 Python 2 和 3 年到它的末尾。 (虽然你正在调查的过程没有改变,但元类的声明方式 - 但给我的 "auf, this is old" 是带参数的 super
)