python new和init知识点
__new__ 方法是什么?
如果将类比喻为工厂,那么__init__()方法则是该工厂的生产工人,__init__()方法接受的初始化参 数则是生产所需原料,
__init__()方法会按照方法中的语句负责将原料加工成实例以供工厂出货。而 __new__()则是生产部经理,
__new__()方法可以决定是否将原料提供给该生产部工人,同时它还决定着出 货产品是否为该生产部的产品,
因为这名经理可以借该工厂的名义向客户出售完全不是该工厂的产品。
__new__方法是真正的创建实例的,决定了,该类能否创建实例
__new__()方法特性:
1.__new__()方法是在类准备将自身实例化时调用。
2.__new__()方法始终都是类的静态方法,即使没有被加上静态方法装饰器。静态方法只有被类能够调用
一个类可以有多个位置参数和多个关键字参数,而在实例化开始之后,在调用 __init__()方法之前,Python首先调用__new__()方法:
def __new__(cls, *args, **kwargs):
...
如果要得到当前类的实例,应当在当前类中的__new__()方法语句中调用当前类的父类 的__new__()方法
例如,如果当前类是直接继承自object,那当前类的__new__()方法返回的对象应该为:
def __new__(cls, *args, **kwargs):
...
return object.__new__(cls)
(事实上如果(新式)类中没有重写__new__()方法,即在定义新式类时没有重新定义__new__()时 ,
Python默认是调用该类的直接父类的__new__()方法来构造该类的实例,如果该类的父类也没有重写 __new__(),
那么将一直按此规矩追溯至object的__new__()方法,因为object是所有新式类的基类。)
__new__方法接受的参数虽然也是和__init__一样,但__init__是在类实例创建之后调用,而 __new__方法正是创建这个类实例的方法。
当你实例化一个类的时候,具体的执行逻辑是这样的:
p = Person(name, age)
首先使用name和age参数来执行Person类的__new__方法,这个__new__方法会 返回Person类的一个实例
(通常情况下是使用 super(Persion, cls).__new__(cls, ... ...) 这样的方式),
然后利用这个实例来调用类的__init__方法,上一步里面__new__产生的实例也就是 __init__里面的的 self
所以,__init__ 和 __new__ 最主要的区别在于:
__init__ 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
__new__ 通常用于控制生成一个新实例的过程。它是类级别的方法。
__new__ 的作用
依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple),
提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass。
在python中,真正创建实例的是__new__方法,这个方法是基于类的层面,__init__是实例创建出来之后,对类进行定制的,基于实例级别的
用__new__来实现单例模式
因为类每一次实例化产生的过程都是通过__new__来控制的,所以通过重载__new__方法,我们 可以很简单的实现单例模式。
===================
__new__() 函数只能用于从object继承的新式类
object将__new__()方法定义为静态方法,并且至少需要传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供
__new__()必须要有返回值,返回实例化出来的实例,需要注意的是,可以return父类__new__()出来的实例,也可以直接将object的__new__()出来的实例返回
===================
例子1
class Demo(object):
def __init__(self):
print '__init__() called...'
def __new__(cls, *args, **kwargs):
print '__new__() - {cls}'.format(cls=cls)
return object.__new__(cls, *args, **kwargs)
if __name__ == '__main__':
de = Demo()
例子2
class Parent(object):
def __new__(cls):
print "Parent __new__ called"
return object.__new__(cls)
class Demo(Parent):
def __init__(self):
print "__init__ called"
def __new__(cls):
print "__new__ called"
return Parent.__new__(cls)
d= Demo()
输出:
__new__ called
Parent __new__ called
__init__ called
__new__方法是一级一级往上回溯走的,从父类最终到祖宗类object,也可以直接调用祖宗类object的__new__方法生成实例
发现实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法
__new__()必须要有返回值,返回实例化出来的实例,需要注意的是,可以return父类__new__()出来的实例,
也可以直接将object的__new__()出来的实例返回。
__init__()有一个参数self,该self参数就是__new__()返回的实例,__init__()在__new__()的基础上可以完成一些其它初始化的动作,
__init__()不需要返回值。
若__new__()没有正确返回当前类cls的实例,那__init__()将不会被调用,即使是父类的实例也不行。
我们可以将类比作制造商,__new__()方法就是前期的原材料购买环节,__init__()方法就是在有原材料的基础上,加工,初始化商品环节。
(这个类比比较好,new方法完以后,就出来了一个实例,可以认为这个实例还没有任何内容,空的,可以在这个阶段对这个类增加一些新属性,但是仅仅是对类
还不能对类实例操作,__init方法完以后,对这个实例进行了一些修饰,粉饰,这个阶段可以对类和实例,都进行属性的修改增加等操作)
类属性的访问,可以通过类或者实例,但是类属性的修改,只能通过类方式
默认的__new__方法会从子类开始一直调用父类的__new__方法,直到最后调用object的__new__方法。
但每次调用时传入的cls参数都是子类的类对象,所以最终能产生子类对象
===============
__new__()是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在Python 中 存在于类里面的构造方法__init__()负责将类的实例化,
而在__init__()启动之前,__new__()决定是否 要使用该__init__()方法,
因为__new__()可以调用其他类的构造方法或者直接返回别的对象来作为本类 的实例
通常来说,新式类开始实例化时,__new__()方法会返回cls(cls指代当前类)的实例,
然后该类的 __init__()方法作为构造方法会接收这个实例(即self)作为自己的第一个参数,然后依次传入__new__ ()方法中接收的位置参数和命名参数。
注意:如果__new__()没有返回cls(即当前类)的实例,那么当前类的__init__()方法是不会被调用 的。
如果__new__()返回其他类(新式类或经典类均可)的实例,那么只会调用被返回的那个类的构造方 法。
================
在任何新式类的__new__()方法,不能调用自身的__new__()来制造实例,因为这会造成死循环
使用object或者没有血缘关系的新式类的__new__()是安全的,但是如果是在有继承关系的两个类之间,应避免互调造成死循环
===============
因此可以这么描述__new__()和__ini__()的区别,在新式类中__new__()才是真正的实例化方法,为类
提供外壳制造出实例框架,然后调用该框架内的构造方法__init__()使其丰满。
# 如果以建房子做比喻,__new__()方法负责开发地皮,打下地基,并将原料存放在工地。而__init__()
方法负责从工地取材料建造出地皮开发招标书中规定的大楼,__init__()负责大楼的细节设计,建造,装修使其可交付给客户
python new和init知识点的更多相关文章
- python类内init外声明的属性与init内声明的对象属性的访问和操作区别
python类内init外声明的属性与init内声明的对象属性的访问和操作区别(面试题) 1.在ipython中输入以下代码,其输出会是什么? In [1]: class ClassOut: ...: ...
- Python OS模块重要知识点
Python OS模块重要知识点 这几点很重要,主要是关于文件路径,我之前踩了很多坑,今天总结一下,方便以后能够避免与path相关的各种坑! 1,首先我们想获取某个文件夹下面的所有文件夹以及文件(不包 ...
- python - 那些零碎的知识点
python - 那些零碎的知识点 一. 字符串格式化 1. "旧式字符串解析(%操作符)" 'Hello, %s' % name "Hello, Bob" ' ...
- Day8 Python基础之遗漏知识点(六)
1. 遗漏知识点 深.浅拷贝: http://www.cnblogs.com/yuanchenqi/articles/5782764.html a=b: 浅拷贝: 深拷贝 集合(set) 集合的定 ...
- python基础语法及知识点总结
本文转载于星过无痕的博客http://www.cnblogs.com/linxiangpeng/p/6403991.html 在此表达对原创作者的感激之情,多谢星过无痕的分享!谢谢! Python学习 ...
- Python面向对象几个知识点
一.判断对象是否属于类.判断类是否派生自某个类 class Zero: pass class One(Zero): pass class Two(One, Zero): pass # 判断对象是否完全 ...
- Python需要知道的知识点
1.所有数据类型都自带布尔值,布尔值为假的数据类型 包括( 空字符串,空列表,空字典,空集合).数字(0).None类型 2.Python实现int的时候有个小整数池.为了避免因创建相同的值而重复申请 ...
- Python常用基础语法知识点大全
记得我是数学系的,大二时候因为参加数学建模,学习Python爬虫,去图书馆借了一本Python基础书,不厚,因为有matlab和C语言基础,这本书一个星期看完了,学完后感觉Python入门很快,然后要 ...
- Python语言及其应用 - 知识点遍历
遍历python语法 2.基本元素:数字.字符串和变量 2.1 python有哪些基本类型? 布尔型(True, False),整型(42,100000),浮点型(3.14159,1.0e8) ...
随机推荐
- Java进阶(八)Java加密技术之对称加密 非对称加密 不可逆加密算法
对称加密 非对称加密 不可逆加密算法 根据密钥类型不同可以将现代密码技术分为两类:对称加密算法(私钥密码体系)和非对称加密算法(公钥密码体系). 1 对称加密算法 原理 对称加密算法中,数据加密和解密 ...
- hadoop环境配置过程中可能遇到问题的解决方案
Failed to set setXIncludeAware(true) for parser 遇到此问题一般是jar包冲突的问题.一种情况是我们向java的lib目录添加我们自己的jar包导致had ...
- android升级后错误:Unable to execute dex: java.nio.BufferOverflowException.Check
Android SDK Tools升级为22.3,Android SDK Platform-tools 升级为19后,编译工程出现错误: Unable to execute dex: java.nio ...
- session效率
(1)-不恰当的request.getSession() 在HttpServlet中,HttpSession对象通常在request.getSession(true)方法调用时才创建. HttpSes ...
- Media Player Classic - HC 源代码分析 5:关于对话框 (CAboutDlg)
===================================================== Media Player Classic - HC 源代码分析系列文章列表: Media P ...
- 利用JQuery直接调用asp.net后台方法
利用JQuery的$.ajax()可以很方便的调用asp.net的后台方法. [WebMethod] 命名空间 1.无参数的方法调用, 注意:1.方法一定要静态方法,而且要有[WebMethod] ...
- myBatis源码之Executor、BaseExecutor和CachingExecutor
接下来是mybatis的执行过程,mybatis提供了一个接口Executor,Executor接口主要提供了update.query方法及事物相关的方法接口 /** * @author Clinto ...
- 在Mac中使用「dd」指令烧录ISO镜像文件到U盘
作者:超級efly 發布:2014-07-26 20:22 分類:電腦 閱讀:442 11條評論 大家在Windows系統下可以方便的使用UltraISO程式來燒錄「.ISO」, ...
- Python list 两个不等长列表交叉合并
遇到一个需求,需要对两个长度不一定相等的列表进行交叉合并.像拉拉链一样(两边的拉链不一定相等). 如: a = [1, 3, 5] b = [2, 4, 6, 8] 需将a, b 合并为 c c = ...
- minimun depth of binary tree
Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...