我想知道解释器在幕后所做的所有操作的顺序是什么(无论是否明确声明它们)。
例如:
__init__
致电super()
致电__new__
致电编辑:让我们假设它是一个拥有它的所有类(你的名字)
global_var = 2468
class A(superA):
class_var = 1234
__init__(self):
superA.__init__(self)
another_var = 5678
@random_decorator
def method(self):
# do stuff
答案 0 :(得分:4)
class Foo(object):
def __init__(self, *args, **kwargs):
pass
>>> foo = Foo(a, b=c)
type.__call__(Foo, a, b=c)
... (而type
可以是您班级的元类) Foo.__new__(a, b=c)
创建Foo
... foo.__init__(a, b=c)
并返回foo
。换句话说,b = B(*args)
的作用类似type.__call__(B, *args)
,其中type.__call__
可表示为:
class type(object):
def __call__(cls, *args, **kwargs)
obj = cls.__new__(*args, **kwargs)
obj.__init__(*args, **kwargs)
return obj
函数super
只在你调用它的地方执行(就像普通函数一样)。
装饰是在类和方法的初始化中执行的,在包装器上替换它们。
完整示例:
def dec(func):
print 'decorate', func.__name__
def wrapper(*args):
print 'call wrapper of', func.__name__
return func(*args)
return wrapper
class A(object):
def __new__(*args):
print 'call A.__new__'
return object.__new__(*args)
def __init__(self, *args):
print 'call A.__init__'
class MyMetaclass(type):
def __call__(mcls, *args):
print 'call MyMetaclass.__call__'
return super(MyMetaclass, mcls).__call__(*args)
class B(A):
__metaclass__ = MyMetaclass
@dec
def __new__(*args):
print 'call B.__new__'
return A.__new__(*args)
@dec
def __init__(self, *args):
print 'call B.__init__'
return super(B, self).__init__(*args)
print 'start creating instance'
b = B()
print 'end creating instance'
结果:
decorate __new__
decorate __init__
start creating instance
call MyMetaclass.__call__
call wrapper of __new__
call B.__new__
call A.__new__
call wrapper of __init__
call B.__init__
call A.__init__
end creating instance
答案 1 :(得分:2)
这一切都很简单。加载模块时,代码从顶部到底部运行。因此,全局变量将在模块代码中出现时进行实例化。调用函数时,函数中的代码从上到下运行。
装饰器有点例外,因为它们在装饰它们的功能之后被调用,从下到上依次定义。所以如果你有:
@hits
@dies
@rofls
def watcher(): pass
它与:
相同def watcher(): pass
watcher = hits(dies(rofls(watcher)))
如果你想到每个装饰包装下面的所有内容,这是有道理的。
创建对象后,首先调用__new__
,然后调用__init__
。如果碰巧在某个地方调用它,就会调用super()
,就像其他任何东西一样......只要你在__init__
中进行变量赋值,就会初始化“构造函数变量”。
编辑:看看你的例子:
class A(superA):
class_var = 1234
def __init__(self):
superA.__init__(self)
another_var = 5678
@random_decorator
def method(self):
# do stuff
我会教你如何钓鱼。
def random_decorator(f):
print "random_decorator called"
return f
def init_var(varname, val):
print '%s being initialized' % (varname,)
return val
class superA(object):
def __new__(cls):
print 'superA.__new__ called'
return super(superA, cls).__new__(cls)
def __init__(self):
print "superA.__init__ called"
class A(superA):
class_var = init_var('class_var', 1234)
def __new__(cls):
print 'A.__new__ called'
return super(A, cls).__new__(cls)
def __init__(self):
print 'A.__init__ called'
superA.__init__(self)
another_var = init_var('another_var', 5678)
@random_decorator
def method(self):
print 'method called'
# do stuff
class_var2 = init_var('class_var2', 9012)
A().method()
查看印刷语句的顺序。