详解python中的__init__与__new__方法
一、__init__和__new__方法执行的顺序?
在面向对象中介绍了关于对象创建的过程,我们知道__new__方法先于__init__方法执行。
二、__new__方法是什么?
首先,我们先来看下下面的代码
class person(object):
def __init__(self,name,age):
self.age=age
self.name=name
print('exec init....')
def __new__(cls, *args,**kwargs):
print('exec new....')
return super(person,cls).__new__(cls) obj1=person('wd',22)
执行结果:
exec new....
exec init....
上面代码告诉了我们,执行init之前new方法执行了,并且代码中重构了父类的new方法,在上一篇面向对象过程中解释了类创建过程,执行new的过程就是person类创建的过程,所以__new__方法实际上就是创建这个类实例方法。(这里指的是person类)
说明下上述代码的执行过程:
1.当解释器解释到obj1=person('wd',22)时候,先执行__new__(cls,*args,**kwargs),并执行父类的__new__方法,将name,age参数传入父类__new__方法,创建person。
2.类创建完成以后,在调用__init__方法,将wd和22参数传入创建对象。
三、__init__与__new__的区别
从上述过程中我们可以发现,这两个方法区别在于:
1.__init__ 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
2.__new__ 通常用于控制生成一个类实例的过程。它是类级别的方法。
四、__new__的作用
依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass。
首先我们来看一下一个功能,自定义类似int类功能,使用int类整数化以后将数变为非负数(大于0)。
class myint(int):
def __new__(cls, *args,**kwargs):
print('exec new....')
return super(myint,cls).__new__(cls,abs(*args)) print(myint(-1))#自定义int类
print(int(-1))#自带的int类
结果:
exec new....
1
-1
五、通过__new__方法实现单实例
单例模式,可以简单理解为实例化后生成的每个实例都是完全一样的。
class Single(object):
def __new__(cls):
if not hasattr(cls, 'myinstance'):
cls.myinstance = super(Single, cls).__new__(cls)
return cls.myinstance#每次生成的都是同一个实例 obj1 = Single()
obj2 = Single() obj1.attr1 = 'wd'
print(obj1.attr1, obj2.attr1)
print(obj1 is obj2)#返回True表明是同一个实例
结果:
wd wd
True
详解python中的__init__与__new__方法的更多相关文章
- 详解Python中的__init__和__new__(静态方法)
一.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: #-*- co ...
- 详解Python中的__init__和__new__
转载:https://my.oschina.net/liuyuantao/blog/747164 1.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ ...
- python中的__init__ 、__new__、__call__小结
这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs) 创建对象时调用,返回 ...
- 举例详解Python中的split()函数的使用方法
这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:sp ...
- 详解Python中re.sub--转载
[背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...
- 详解Python中内置的NotImplemented类型的用法
它是什么? ? 1 2 >>> type(NotImplemented) <type 'NotImplementedType'> NotImplemented 是Pyth ...
- Python中的__init__和__new__
一.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- c ...
- python中的__init__和__new__的区别
一.__init__ 方法是什么?(init前后的线是双下划线) 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例 ...
- python类中的__init__和__new__方法
Python中类: Python中在创建类的过程中最先调用的不是__init__方法而是__new__方法,__new__方法是一个静态方法,在创建一个类对象时其实是通过__new__方法首先创建出一 ...
随机推荐
- Head First设计模式之解释器模式
一.定义 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子. 主要解决:对于一些固定文法构建一个解释句子的解释器. 何时使用:如果一种特定类型的问题发生的频率足 ...
- python字符集的转换(mysql数据乱码的处理)
本文参考:http://blog.csdn.net/crazyhacking/article/details/39375535 chardet模块:http://blog.csdn.net/tianz ...
- vue2.0 正确理解Vue.nextTick()的用途
什么是Vue.nextTick() 官方文档解释如下: 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 获取更新后的DOM,言外之意就是DOM更新 ...
- 【后缀自动机】洛谷P3804模板题
题目描述 给定一个只包含小写字母的字符串SSS, 请你求出 SSS 的所有出现次数不为 111 的子串的出现次数乘上该子串长度的最大值. 输入输出格式 输入格式: 一行一个仅包含小写字母的字符串SSS ...
- Python网络编程篇之socket
1 socket 插座?呵呵,想多了,翻译过来意思是套接字! A network socket is an internal endpoint for sending or receiving dat ...
- vi/vim 如何添加和删除多行注释
1.进入vi/vim编辑器,按CTRL+V进入可视化模式(VISUAL BLOCK). 2.移动光标上移或者下移,选中多行的开头. 3.选择完毕后,按大写的I键,此时下方会提示进入"inse ...
- IdentityServer(15)- 第三方快速入门和示例
这些示例不由IdentityServer团队维护. IdentityServer团队提供链接到了社区示例,但不能对示例做任何保证. 如有问题,请直接与作者联系. 各种ASP.NET Core安全示例 ...
- Zabbix实战-简易教程--技巧(本地化)
1.zabbix的logo图标替换(不建议修改) 3.0版本以下: 1.修改/usr/share/zabbix/include/page_header.php 2.修改/usr/share/zabbi ...
- java中注解的使用
使用过ssh框架的人一定也使用过注解,尤其是在spring框架中,注解可谓是spring容器和AOP编程的重要环节.注解就是用于修饰类.全局变量.方法.参数或局部变量的接口,java中规定,注解的使用 ...
- java调用c++函数的简单笔记
java使用jni调用c++动态库函数. 步骤: 1.编写java测试代码如下: public class CallNativeDemo { native void func(); native do ...