在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A())

新式类跟经典类的差别主要是以下几点:
  1. 新式类对象可以直接通过__class__属性获取自身类型:type
  2. 继承搜索的顺序发生了改变,经典类多继承时属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧(即深度优先搜索);新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动

例子:

经典类: 搜索顺序是(D,B,A,C)
>>> class A: attr = 1
...
>>> class B(A): pass
...
>>> class C(A): attr = 2
...
>>> class D(B,C): pass
...
>>> x = D()
>>> x.attr
1

新式类继承搜索程序是宽度优先

新式类:搜索顺序是(D,B,C,A)
>>> class A(object): attr = 1
...
>>> class B(A): pass
...
>>> class C(A): attr = 2
...
>>> class D(B,C): pass
...
>>> x = D()
>>> x.attr
2
  3. 新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中。
  4. 新式类增加了__getattribute__方法

  5.新式类内置有__new__方法而经典类没有__new__方法而只有__init__方法
注意:Python 2.x中默认都是经典类,只有显式继承了object才是新式类
     而Python 3.x中默认都是新式类(也即object类默认是所有类的祖先),不必显式的继承object(可以按照经典类的定义方式写一个经典类并分别在python2.x和3.x版本中使用dir函数检验下。

例如:class A():

      pass

    print(dir(A))

会发现在2.x下没有__new__方法而3.x下有。

接下来说下__new__方法和__init__的区别:

在python中创建类的一个实例时,如果该类具有__new__方法,会先调用__new__方法,__new__方法接受当前正在实例化的类作为第一个参数(这个参数的类型是type,这个类型在c和python的交互编程中具有重要的角色,感兴趣的可以搜下相关的资料),其返回值是本次创建产生的实例,也就是我们熟知的__init__方法中的第一个参数self。那么就会有一个问题,这个实例怎么得到?

注意到有__new__方法的都是object类的后代,因此如果我们自己想要改写__new__方法(注意不改写时在创建实例的时候使用的是父类的__new__方法,如果父类没有则继续上溯)可以通过调用object的__new__方法类得到这个实例(这实际上也和python中的默认机制基本一致),如:

class display(object):
def __init__(self, *args, **kwargs):
print("init")
def __new__(cls, *args, **kwargs):
print("new")
print(type(cls))
return object.__new__(cls, *args, **kwargs)
a=display()

运行上述代码会得到如下输出:

new
<class 'type'>
init
因此我们可以得到如下结论:

在实例创建过程中__new__方法先于__init__方法被调用,它的第一个参数类型为type。

如果不需要其它特殊的处理,可以使用object的__new__方法来得到创建的实例(也即self)。

于是我们可以发现,实际上可以使用其它类的__new__方法类得到这个实例,只要那个类或其父类或祖先有__new__方法。

class another(object):
def __new__(cls,*args,**kwargs):
print("newano")
return object.__new__(cls, *args, **kwargs)
class display(object):
def __init__(self, *args, **kwargs):
print("init")
def __new__(cls, *args, **kwargs):
print("newdis")
print(type(cls))
return another.__new__(cls, *args, **kwargs)
a=display()

上面的输出是:

newdis
<class 'type'>
newano
init
所有我们发现__new__和__init__就像这么一个关系,__init__提供生产的原料self(但并不保证这个原料来源正宗,像上面那样它用的是另一个不相关的类的__new__方法类得到这个实例),而__init__就用__new__给的原料来完善这个对象(尽管它不知道这些原料是不是正宗的)

python中的__new__与__init__,新式类和经典类(2.x)的更多相关文章

  1. Python中的__new__和__init__

    Python中的__new__和__init__ 写了这么多的class,现在才知道还有个__new__方法, 那么它和__init__有什么区别呢? class TestCls(): "& ...

  2. Python 中的__new__和__init__的区别

    [同] 二者均是Python面向对象语言中的函数,__new__比较少用,__init__则用的比较多. [异] __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例对象,是 ...

  3. 一个案例深入Python中的__new__和__init__

    准备 在Python中,一切皆对象. 既然一切皆对象,那么类也是对象,我们暂且称之为 类对象.来个简单例子(本篇文章的所有案例都是运行在Python3.4中): class foo(): pass p ...

  4. python中的__new__、__init__和__del__

    __new__.__init__.__del__三个方法用于实例的创建和销毁,在使用python的类中,我们最常用的是__init__方法,通常称为构造方法,__new__方法几乎不会使用,这篇文章是 ...

  5. 详解Python中的__new__、__init__、__call__三个特殊方法(zz)

    __new__: 对象的创建,是一个静态方法,第一个参数是cls.(想想也是,不可能是self,对象还没创建,哪来的self)__init__ : 对象的初始化, 是一个实例方法,第一个参数是self ...

  6. python 中的__new__与__init__

    在Python中的class中有两个方法__new__与__init__,有什么区别呢? class TestCls(): """docstring for TestCl ...

  7. python2中的__new__与__init__,新式类和经典类-乾颐堂

    在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...

  8. python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。

    单例模式的写法非常多,但常规型的单例模式就是这样写的,各种代码可能略有差异,但核心就是要搞清楚类属性 实例属性,就很容易写出来,原理完全一模一样. 如下: 源码: class A(object): d ...

  9. python中新式类和经典类

    python中的类分为新式类和经典类,具体有什么区别呢?简单的说, 1.新式类都从object继承,经典类不需要. Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Pyth ...

随机推荐

  1. mybatis查询语句的背后之参数解析

    转载请注明出处... 一.前言 通过前面我们也知道,通过getMapper方式来进行查询,最后会通过mapperMehod类,对接口中传来的参数也会在这个类里面进行一个解析,随后就传到对应位置,与sq ...

  2. switch反汇编

    以下总结为debug模式

  3. vue中的jsx

    一.配置文件package.json { "name": "vuetest", "version": "1.0.0", ...

  4. Vuejs学习笔记(一)

    1)    vue.js 的 主要功能 1.模板渲染 2.模块化 3.扩展功能:路由,Ajax 2)    vue.js 模板渲染之双向绑定示例 message 绑定到了 input 对象,所有在in ...

  5. java 使用CRF遇到的问题汇总

    1.libCRFPP.so放在idea项目 resources下,打jar包时打在jar中. jar包工具类 /* * Class NativeUtils is published under the ...

  6. 现阶段如何开始使用v-ray for unrealengine

    如何安装 因为现阶段v-ray for unrealengine还处于beta测试阶段所以你必须去https://www.chaosgroup.com/vray/unreal 申请测试资格申请完之后就 ...

  7. 洛谷.3805.[模板]manacher算法

    题目链接 之前做很早了没写这篇,补上. 记录当前ex[]最大的回文中心id和最远延伸范围mx! 关于串的构造: 应该是 @ #A#B#C#B#A# $ ,而不是 @ A#B#C#B#A $ 比如 @a ...

  8. 使用scrapy爬取百度股票

    1.spiders文件夹下的爬虫文件 # -*- coding: utf-8 -*- import scrapy import re import random from scrapy.http.re ...

  9. [BZOJ3339]Rmq Problem / mex

    Description: 有一个长度为n的数组{a1,a2,-,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Hint: \(n \le 2*10^5\) Solution: 主席树好 ...

  10. 第2讲——wiz

    PC端信息收集 网页剪藏 win+s 屏幕截图:win+printscreen微博收集:@mywiz  @我的印象笔记 按ESC隐藏/恢复左边导航栏 F11全屏阅读  打标签:解决文件夹重叠问题 搜索 ...