在实例化对象时,解释器所执行的操作是什么?

时间:2012-10-11 13:52:31

标签: python

我想知道解释器在幕后所做的所有操作的顺序是什么(无论是否明确声明它们)。

例如:

  • __init__致电
  • super()致电
  • __new__致电
  • 全局变量
  • 构造函数变量的初始化
  • decorators调用等。

编辑:让我们假设它是一个拥有它的所有类(你的名字)

global_var = 2468
class A(superA):
    class_var = 1234

    __init__(self):
        superA.__init__(self)
        another_var = 5678

    @random_decorator
    def method(self):
        # do stuff

2 个答案:

答案 0 :(得分:4)

class Foo(object):
    def __init__(self, *args, **kwargs):
        pass

>>> foo = Foo(a, b=c)
  1. 致电type.__call__(Foo, a, b=c) ... (而type可以是您班级的元类)
  2. ...调用Foo.__new__(a, b=c)创建Foo ...
  3. 的实例
  4. ...并致电foo.__init__(a, b=c)并返回foo
  5. 换句话说,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()

查看印刷语句的顺序。