Python实例化class的执行顺序

Python里对类的实例化时有怎样的顺序
通常来讲一个类里面有类变量和方法,好比咱们定义一个名为A的类python

class A():
    bar = "my lover love me"
    
    def __init__(self, name):
        print('A的class' ,self.__class__, name)

咱们在这个类里面定义了一个类变量bar和一个构造方法__init__,那么咱们实例化A()时都发生了什么呢!看官不要急,听我慢慢道来...this

  • 首先,python 调用内置的type类,没有听错,就是咱们平时用来测引用类型的那个type,而后type调用内置的元类mateClass,mateClass再调用__new__方法将类实例化,此时完成了第一步
  • 而后,这个实例将会初始化本身的类变量,就是把本身从头至尾扫视一遍,
  • 以后,进入构造方法,并初始化本身的实例变量。

注意:python中类变量和实例变量是不同的,

类变量:不用实例化也能够访问。
实例变量:是动态建立的。必须实例化以后才能够访问,由于以前是不存在的。翻译

好比下面这个例子:不实例化访问类变量code

class A():
    a = 2
print(A.a)

输出:
>>>2

说了这么多,上代码。看看类继承时怎么运行的:对象

class A():
    def __init__(self, name):
        print('A的class' ,self.__class__, name)
        
class B(A):
    def __init__(self, name):
        self._name = name
        A.__init__(self, name)
        print('B的class', self.__class__, name)
    print('this is B class')
        
class C(B):
    def __init__(self, name):
        B.__init__(self, name)
        print('C的class')
        
if __name__ == '__main__':

c = C('lee')

输出以下:继承

this is B class
A class <class '__main__.C'> lee
B class <class '__main__.C'> lee
C class

来现身说法,解释一波文档

  • 首先对class C()进行实例化,从头至尾扫一遍,而后进入C()的构造,遇到了父类C()的构造方法B.__init__。
  • 进入class B(),从头至尾扫一遍,执行了print('this is B class')语句而后进入B()的构造,遇到了父类B()的构造方法A.__init__。
  • 进入class A(),从头至尾扫一遍,而后进入A()的构造方法A.__init__。而后A.__init__执行完毕并弹出栈,class A()执行完毕并弹出栈。
  • 回到class B(),从上次未执行完的地方print('B的class', self.__class__, name)继续执行。而后B.__init__执行完毕并弹出栈,class B()执行完毕并弹出栈。
  • 回到class C(),从上次未执行完的地方print('C的class')继续执行。而后C.__init__执行完毕并弹出栈,class C()执行完毕并弹出栈。程序运行完毕。
  • 因为是对class C()进行实例化,上面的self都是指class C()的实例而不是class A()的或者class B()的。所以self.__class__清一色的显示<class '__main__.C'>而不是<class '__main__.A'>或<class '__main__.B'>。

随便补充一下使用type关键字动态建立类的知识点,敲黑板、、、我要用CET3.5的英语水平向你们翻译一部分官方文档对type的描述啦。字符串

使用三个参数,返回一个新类型对象。这其实是类语句的动态形式。名称字符串是类名,并成为 __name__属性;基元元组列出基类并成为> __bases__属性;而且dict字典是包含类主体定义的命名空间,并被复制到标准字典以成为 __dict__属性。

怎么样,是否是很拗口,是否是大写的懵*。so,上代码,如下两种写法输出同样的都是输出:重写name方法 1it

class X():
    a = 1
    def __name__(self):
    return '重写name方法'   
x =X()
print(x.__name__(), x.a)

X = type('重写name方法', (object,), dict(a = 1))
x = X()
print(X.__name__, x.a)

type动态建立实例化时,第一个参数就至关于重写了类的__name__方法。X类但__name__属性却不叫X,呵,好反人类的写法
还好咱们通常不是这么变态,一般咱们会将这两个定义成相同的名字,以下:都叫X
X = type('X', (object,), dict(a = 1))
欢迎你们踊跃评论,提出建议哦~class

先更新到这里。。。。 2018/10/09

相关文章
相关标签/搜索