资讯专栏INFORMATION COLUMN

Python实例化class的执行顺序

remcarpediem / 2279人阅读

摘要:实例变量是动态创建的。必须实例化之后才可以访问,因为之前是不存在的。看看类继承时怎么运行的的的的输出如下来现身说法,解释一波首先对进行实例化,从头到尾扫一遍,然后进入的构造,遇到了父类的构造方法。然后执行完毕并弹出栈,执行完毕并弹出栈。

Python里对类的实例化时有怎样的顺序
一般来说一个类里面有类变量和方法,比如我们定义一个名为A的类

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

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

首先,python 调用内置的type类,没有听错,就是我们平时用来测引用类型的那个type,然后type调用内置的元类mateClass,mateClass再调用__new__方法将类实例化,此时完成了第一步

然后,这个实例将会初始化自己的类变量,就是把自己从头到尾扫视一遍,

之后,进入构造方法,并初始化自己的实例变量。

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

类变量:不用实例化也可以访问。
实例变量:是动态创建的。必须实例化之后才可以访问,因为之前是不存在的。

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

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 lee
B class 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__清一色的显示而不是

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

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

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

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,呵,好反人类的写法
还好我们一般不是这么{{BANNED}},通常我们会将这两个定义成相同的名字,如下:都叫X
X = type("X", (object,), dict(a = 1))
欢迎大家踊跃评论,提出建议哦~

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42608.html

相关文章

  • Python理解面向对象

    摘要:面向对象编程,简称,是一种程序设计思想。面向过程与面向对象面向过程的程序设计把函数作为程序的基本单元。以上是在计算机世界里认识面向对象和面向过程,接下来给大家举个生活中的例子就拿你早上想吃鸡蛋灌饼为例。 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。 面向过程 ...

    hatlonely 评论0 收藏0
  • Python基础之(八)类

    摘要:方法绑定方法多重继承实例化实现了方法和实例的绑调用绑定方法非绑定方法在子类中,父类的方法就是非绑定方法,因为在子类中,没有建立父类的实例,却要是用父类的方法。 类 创建类 第一形式 # !/usr/bin/env python # coding=utf-8 class Person(object): #object表示继承自object类,Python3中可省略次内容 ...

    Freeman 评论0 收藏0
  • Python_OOP

    摘要:魔法方法类构造方法魔法方法初始化对象创建对象的过程创建一个对象解释器会自动的调用方法返回创建的对象的引用,给实例实例化执行该方法,返回值。当引用计数为时,该对象生命就结束了。 define class class的三个组成部分: 类的名称:类名 类的属性: 一组数据 类的方法:允许对进行操作的方法(行为) 定义 class Student (object): pass...

    tyheist 评论0 收藏0
  • SICP Python 描述 2.5 面向对象编程

    摘要:类似消息传递中的分发字典,对象响应行为请求。消息传递和点表达式方法定义在类中,而实例属性通常在构造器中赋值,二者都是面向对象编程的基本元素。使用带有内建对象系统语言的优点是,消息传递能够和其它语言特性,例如赋值语句无缝对接。 2.5 面向对象编程 来源:2.5 Object-Oriented Programming 译者:飞龙 协议:CC BY-NC-SA 4.0 面向对象编程...

    starsfun 评论0 收藏0
  • Python中继承优缺点

    摘要:本文重点不要试图在内置类型的子类中重写方法,可以继承的可拓展类寻求变通掌握多重继承中的和了解处理多重继承的一些建议。子类化的代码如下输出小结上述问题只发生在语言实现的内置类型子类化情况中,而且只影响直接继承内置类型的自定义类。 导语:本文章记录了本人在学习Python基础之面向对象篇的重点知识及个人心得,打算入门Python的朋友们可以来一起学习并交流。 本文重点: 1、不要试图在内置...

    Sourcelink 评论0 收藏0

发表评论

0条评论

remcarpediem

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<