深入解析类对象与类实例的创建过程


class MyType(type):    def __init__(self,*args,**kwargs):        print("init")        super(MyType, self).__init__(*args,**kwargs)

    def __new__(cls, *args, **kwargs):        print("new")        print("mro",cls.__mro__)        # 调用父类的__new__ 方法来实例出一个Base类对象        return super(MyType, cls).__new__(cls, *args, **kwargs)

    def __call__(self, *args, **kwargs):        # self = Base类对象        # 调用object类的__new__方法,创建Base的实例对象        obj = object.__new__(self)        # 执行 构造方法        obj.__init__()        print(‘obj‘,obj)        return obj

class Base(metaclass=MyType):    def __init__(self):        print("Base init")

    def __new__(cls, *args, **kwargs):        ret = super(Base, cls).__new__(cls, *args, **kwargs)        print("Base ret",ret)        return ret

a = Base()print(a,‘a的返回值‘)

  Base是一个对象,Base()则调用创建该类的__call__方法。执行__call__方法本质上是首先执行Base类中的__new__方法,然后再执行__init__方法,最终将生成的经过初始化的实例对象返回给a。也就是说,__call__方法的返回值是什么,生成的实例对象就是什么。需要注意的是,在__call__方法中,self指的是Base对象,因此 obj = object.__new__(self) 生成的是Base类的对象, obj.__init__() 执行的是Base的__init__方法,至此完成了创建Base类实例的过程。

  需要说明的是,我在元类的__call__方法中以手动的方式执行 __new__和__init__,但也可以用  super(MyType, self).__call__(*args, **kwargs) 完成相同的效果,这里只是为了说明   super(MyType, self).__call__(*args, **kwargs) 的内部执行流程。

super补充

  首先要明确的是,super是一个类,不是一个函数。以 super(MyType, self).__call__(*args, **kwargs) 为例,super(cls,ins)获得是cls在ins的mor表中的下一个类对象,再通过该对象调用该对象下的__call__方法,如果此类中没有__call__方法,那么再按照ins的mro表继续向下查找,无论如何,一定可以在object类中找到__call__方法,在__call__方法中首先创建一个cls的实例,然后执行该实例的__init__方法,从而完成cls类的实例。

原文地址:https://www.cnblogs.com/liuyinzhou/p/9728369.html

时间: 2024-08-01 17:17:12

深入解析类对象与类实例的创建过程的相关文章

Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理

上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数 面向对象三大特性:封装.继承和多态 本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 注意点: self ,我们讲过了,self = 对象,实例化后的对象调用类的各种成员的时候的self就是这个对象. 而且我们也讲过了

python类对象、类属性

一."class" 类名:实际上,当解释器执行class语句时,就会创建一个类对象. 二.类属性: 类属性是从属于类对象的属性,也称为"类变量".由于,类属性从属于类对象,可以被所有实例对象共享. class   类名: 类变量名 = 初始值 在类中或者类的外面,我们可以通过:"类名.类变量" 来读写. 原文地址:https://www.cnblogs.com/yingxiongguixing/p/12186077.html

Map<String, Object> 转实体类对象工具类

public static <T> T map2Object(Map<String, Object> map, Class<T> clazz) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (map == null) { return null; } T obj = null; try { // 使用newInstance来创建对象 obj = cla

(一)Python入门-6面向对象编程:02类的定义-类和对象的关系-构造函数-实例属性-实例方法

一:类的定义 如果把对象比作一个“饼干”,类就是制造这个饼干的“模具”. 我们通过类定义数据类型的属性(数据)和方法(行为),也就是说,“类将行为和状态打 包在一起”. 对象是类的具体实体,一般称为“类的实例”.类看做“饼干模具”,对象就是根据这个“模 具”制造出的“饼干”. 从一个类创建对象时,每个对象会共享这个类的行为(类中定义的方法),但会有自己的属 性值(不共享状态).更具体一点:“方法代码是共享的,属性数据不共享”. Python中,“一切皆对象”.类也称为“类对象”,类的实例也称为“

python中类对象、实例对象、类属性、实例属性、类方法、实例方法、静态方法

类对象.类属性与实例对象.实例属性的区别 在Python中一切皆是对象,类是一个特殊的对象即类对象,描述类的属性称为类属性.类属性在内存中只有一份,在__init__外部定义. 通过类创建的对象称为实例对象,描述实例对象的属性称为实例属性.实例属性在各自对象的内存中都保存一份,在__init__方法内部定义. 实例方法.类方法.静态方法的区别 这三种方法都是保存在类的内存中,调用者不同. 实例方法由对象调用,至少一个self参数,self代表对象的引用. 类方法有类调用,至少一个cls参数,并且

黑马程序员_类对象创建代码的执行顺序测试总结

class StaticCode { // 类的非静态成员变量(实例变量)定义语句: // 作用:用来存储对象的特有数据的成员变量. // 运行:当类对象被创建时就执行,按照顺序自上而下执行,和构造代码块平级.(即当有多个构造函数 // 代码块和多个非静态成员变量时,JVM按照自上而下的顺序来执行所有语句,包括构造代码块里的代码 // 和非静态成员的声明.) // 存储位置:非静态变量位于堆内存中的对象实体中. int num = 3; // 构造代码块 { System.out.println

Objective-C对象之类对象和元类对象

作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/8592492 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号wangzzstrive来支持我,谢谢! 作为C语言的超集,面向对象成为Objective-C与C语言的最大区别,因此,对象是Objective-C中最重要的部分之一.目前面向对象的语言有很多,Objective-C中的对象又和其他语言中的对象有什么区别呢?下面来简单介绍Objectiv

类对象可直接访问属性,但未实例化不能调用方法

>>> class MyClass: name = 'FishC' def mufun(self): print('hello Fishc!') >>> MyClass.name#类对象对类的属性进行直接访问 'FishC' >>> MyClass.mufun()#但是类没有实例化,访问其中的方法,则成为不可能. Traceback (most recent call last): File "<pyshell#18>"

24-oc类工厂方法和类对象基本概念

类工厂方法 用于快速创建对象的类方法, 我们称之为类工厂方法 类工厂方法应用场景 类工厂方法中主要用于给对象分配存储空间和初始化这块存储空间 类工厂方法使用规范 规范: 一定是类方法 + 方法名称以类的名称开头, 首字母小写 一定有返回值, 返回值是id/instancetype 在类工厂方法实现中,调用本类的构造方法,创建实例对象,并返回实例对象 自定义类工厂方法是苹果的一个规范, 一般情况下, 我们会给一个类提供自定义构造方法和自定义类工厂方法用于创建一个对象 类工厂方法在继承中的注意点 以