Python中__new__与__init__介绍
在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A())
新式类跟经典类的差别主要是以下几点:
1. 新式类对象可以直接通过__class__属性获取自身类型:type
2. 继承搜索的顺序发生了改变,经典类多继承时属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧(即深度优先搜索);新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动
例子:
经典类: 搜索顺序是(D,B,A,C)
|
1
2
3
4
5
6
7
8
9
10
11
|
>>> class A: attr = 1...>>> class B(A): pass...>>> class C(A): attr = 2...>>> class D(B,C): pass...>>> x = D()>>> x.attr1 |
新式类继承搜索程序是宽度优先
新式类:搜索顺序是(D,B,C,A)
|
1
2
3
4
5
6
7
8
9
10
11
|
>>> class A(object): attr = 1...>>> class B(A): pass...>>> class C(A): attr = 2...>>> class D(B,C): pass...>>> x = D()>>> x.attr2 |
3. 新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中。
4. 新式类增加了__getattribute__方法
5.新式类内置有__new__方法而经典类没有__new__方法而只有__init__方法
注意:Python 2.x中默认都是经典类,只有显式继承了object才是新式类
而Python 3.x中默认都是新式类(也即object类默认是所有类的祖先),不必显式的继承object(可以按照经典类的定义方式写一个经典类并分别在python2.x和3.x版本中使用dir函数检验下。
例如:
|
1
2
3
4
5
|
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中的默认机制基本一致),如:
|
1
2
3
4
5
6
7
8
|
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() |
运行上述代码会得到如下输出:
|
1
2
3
4
5
|
new<class 'type'>init |
因此我们可以得到如下结论:
在实例创建过程中__new__方法先于__init__方法被调用,它的第一个参数类型为type。
如果不需要其它特殊的处理,可以使用object的__new__方法来得到创建的实例(也即self)。
于是我们可以发现,实际上可以使用其它类的__new__方法类得到这个实例,只要那个类或其父类或祖先有__new__方法。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
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() |
上面的输出是:
|
1
2
3
4
|
newdis<class 'type'>newanoinit |
所有我们发现__new__和__init__就像这么一个关系,__init__提供生产的原料self(但并不保证这个原料来源正宗,像上面那样它用的是另一个不相关的类的__new__方法类得到这个实例),而__init__就用__new__给的原料来完善这个对象(尽管它不知道这些原料是不是正宗的)
Python中__new__与__init__介绍的更多相关文章
- python中 __new__和__init__
python这两个函数和类的实例化有关. __init__是实例化完成之后调用的,会对生成的对象实例做一些修饰 __new__是python新类型才有的,它更像是c/c++里面的构造函数,因为这个函数 ...
- Python中__new__和__init__区别
__new__:创建对象时调用,会返回当前对象的一个实例 __init__:创建完对象后调用,对当前对象的一些实例初始化,无返回值 1.在类中,如果__new__和__init__同时存在,会优先调用 ...
- Python中__new__和__init__的区别与联系
__new__ 负责对象的创建而 __init__ 负责对象的初始化. __new__:创建对象时调用,会返回当前对象的一个实例 __init__:创建完对象后调用,对当前对象的一些实例初始化,无返回 ...
- Python 中__new__()和__init__()的区别
转自: https://blog.csdn.net/weixin_37579123/article/details/89515577 __new__方法:类级别的方法 特性: 1.是在类准备将自身实例 ...
- python中self与__init__怎么解释能让小白弄懂?
python中self与__init__怎么解释能让小白弄懂? 这个问题其实没那么简单. 只说一下自己的理解. python 里所有的 object 都有三个属性, 标识(identity), 类型( ...
- python中multiprocessing.pool函数介绍_正在拉磨_新浪博客
python中multiprocessing.pool函数介绍_正在拉磨_新浪博客 python中multiprocessing.pool函数介绍 (2010-06-10 03:46:5 ...
- Python中__new__的作用
__new__ 的作用 依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径.还 ...
- [py]python中__new__作用
元类metaclass 使劲搞,但是没搞清楚__new__的作用 了解Python元类 Python进阶:一步步理解Python中的元类metaclass Python中的__new__和__init ...
- Python中__new__()方法的使用和实例化
new()是在新式类中新出现的方法,它作用在构造方法init()建造实例之前,可以这么理解,在Python 中存在于类里面的构造方法init()负责将类的实例化,而在init()调用之前,new()决 ...
随机推荐
- MFC中控制Tips的显示 - lingyun1120
from: http://www.cnblogs.com/lingyun1120/archive/2011/11/09/2243279.html MFC中为ToolTips生成了一个类CToolTi ...
- 2017 山东二轮集训 Day7 国王
2017 山东二轮集训 Day7 国王 题目大意 给定一棵树,每个点有黑白两种颜色,定义一条简单路径合法当且仅当路径上所有点黑色与白色数量相等,求有多少非空区间 \([L,R]\) ,使得所有编号 \ ...
- Jetty服务怎么配置,如何发布项目
Jetty相对于Tomcat来时相对较轻,适合多并发且有较多实时通讯的系统,能够稳定的保持连接且占用资源相对较少.今天就简单介绍一下Jetty的配置及项目部署. 工具/原料 Jetty 电脑 Jett ...
- Hadoop2.7.1安装与配置
Hadoop2.7.1集群环境的搭建 s204.s205是我的两台服务器hostname,可以用你对应的ip或者hostname代替 工具/原料 jdk.ssh免登录 方法/步骤 1 首先去A ...
- Write operations are not allowed in read-only mode 只读模式下(FlushMode.NEVER/MANUAL)写操作不
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read ...
- WCF NetTcpBinding 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作
背景:WindowsService + WCF + NetTcpBinding 之前一直使用http协议模式,改为net.tcp之后隔段时间出现:由于系统缓冲区空间不足或队列已满,不能执行套接字上的操 ...
- envoy 功能介绍
L3/L4 filter architecture: At its core, Envoy is an L3/L4 network proxy. A pluggable filter chain me ...
- ZenCoding[Emmet]語法簡介【轉】
快速指南 下面是一些常用的Zen Coding功能,目前VS2013的Web Essentials插件已经支持. '#' 创建一个id特性 '.' 创建一个类特性 '[]' 创建一个自定义特性 '&g ...
- 一个工程实例来学习 Makefile
March 3, 2015 8:19 PM Makefile 文件的编写 学习前的准备 需要准备的工程目录结构如下: . ├── add │ ├── add_float.c │ ├── add ...
- 完整的CRUD——javaweb
1,总体架构 index是进去的页面, 可以跳转Insert的增加页面,operatePerson是根据传进来的URI来判断增删改查的页面, DbManager.java是封装的数据库操作类, Pag ...