python的__init__和__new__
本文所有实例代码在python3.7下
一.__new__和__init__区别
1.__new__先于__init__执行;__new__是相当于其他OOP语言的构造方法,负责创建实例;之后,__init__负责初始化实例属性。__new__处理对象创建,__ init__处理对象初始化。
2.__new__是一个特殊的静态方法(没有使用装饰器 @staticmethod);由python解释器调用,如果该类没有__new__,则调用父类的__new__.
3.如果我们创建一个类的实例,代码如下:
class Foo:
def __new__(cls, *args, **kwargs):
return super().__new__(cls) def __init__(self, x, y):
self.__x = x
self.__y = y foo = Foo(10, 20)
__init__返回为None;
__new__返回了一个创建的实例,其后作为__init__中的self传入
4.通过__new__创建实例,通常是
super().__new__(cls)
# cls为当前要创建的类
5.如果__new__返回它自己的类的实例,那么将使用实例作为第一个被调用的__init__方法的self参数,__init__将隐式调用。
如果__new__方法返回除这个类之外的其他实例,则不会调用实例__init__方法。在这种情况下,您必须自己调用__init__方法。
看一个返回类实例之外的例子:
class Foo:
def __init__(self, x):
self.__x = x @property
def x(self):
return self.__x class Bar:
def __new__(cls, *args, **kwargs):
foo = super().__new__(Foo)
foo.__init__(*args, **kwargs)
return foo bar = Bar(10)
print(bar.x)
看一个返回自身类实例的:
class Bar:
def __new__(cls, *args, **kwargs):
foo = super().__new__(cls)
return foo def __init__(self, x):
self.__x = x @property
def x(self):
return self.__x bar = Bar(10)
print(bar.x)
二.__new__的一些用途
大多数情况下都不需要重写__new__。
1.单例模式:
class Foo:
__instance = None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = super().__new__(cls)
return cls.__instance foo1 = Foo()
foo2 = Foo()
print(foo1, foo2)
输出:
<__main__.Foo object at 0x0000029A4B879048> <__main__.Foo object at 0x0000029A4B879048>
可以看出foo1和foo2是同一个实例
2.限制实例的创建数量:
class Foo:
__instance = []
limit = 2
def __new__(cls, *args, **kwargs):
print(len(cls.__instance))
if len(cls.__instance) == cls.limit:
raise RuntimeError("Count not create instance. Limit %s reached" % cls.limit)
instance = super().__new__(cls)
cls.__instance.append(instance)
return instance def __del__(self):
self.__instance.remove(self) foo1 = Foo()
foo2 = Foo()
print(foo1, foo2)
3.自定义实例创建
您可以自定义创建的实例,并在调用初始化程序__init__之前对其进行一些操作。此外,您可以基于某些约束对实例创建施加限制
def is_create():
#根据条件判断是否可以创建
return True class Foo:
def __new__(cls, a, b):
if not is_create():
raise RuntimeError('实例不能被创建')
instance = super().__new__(cls)
instance.count = a + b
return instance def __init__(self, a, b):
pass foo = Foo(1, 2)
print(foo.count)
4.自定义返回的对象
通常,当您实例化类时,它将返回该类的实例。您可以自定义此行为,并且可以返回所需的对象。
class Foo:
def __new__(cls, a, b):
instance = super().__new__(cls)
instance.__init__(a, b)
return a + b
def __init__(self, a, b):
print('a+b') foo = Foo(1, 2)
print(foo)
如果我们不从__new__方法返回实例对象,则必须显式调用__init__。
python的__init__和__new__的更多相关文章
- python 的__init__ 和__new__ 区别
在此介绍一下 __init__ 和 __new__ 先后调用的区别 代码如下: # __init__ 和 __new__的区别 # 通常在编代码时,__init__ 较为常见,但是__new__却 ...
- Python中__init__和__new__的区别详解
__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- cod ...
- python中__init__()、__new__()、__call__()、__del__()几个魔法方法的用法
关于__new__()的用法参考: http://www.myhack58.com/Article/68/2014/48183.htm 正文: 一.__new__()的用法: __new__()是在新 ...
- python中__init__()、__new__()、__call__()、__del__()用法
关于__new__()的用法参考: http://www.myhack58.com/Article/68/2014/48183.htm 正文: 一.__new__()的用法: __new__()是在新 ...
- python中__init__和__new__的区别
参考:https://my.oschina.net/liuyuantao/blog/747164 python中__metaclass的详解 参考:https://www.cnblogs.com/ia ...
- python中的__init__ 、__new__、__call__小结
这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs) 创建对象时调用,返回 ...
- 详解python中的__init__与__new__方法
一.__init__和__new__方法执行的顺序? 在面向对象中介绍了关于对象创建的过程,我们知道__new__方法先于__init__方法执行. 二.__new__方法是什么? 首先,我们先来看下 ...
- Python中的__init__和__new__
一.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- c ...
- python中的__init__和__new__的区别
一.__init__ 方法是什么?(init前后的线是双下划线) 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例 ...
随机推荐
- hihoCoder #1871 : Heshen's Account Book-字符串暴力模拟 自闭(getline()函数) (ACM-ICPC Asia Beijing Regional Contest 2018 Reproduction B) 2018 ICPC 北京区域赛现场赛B
P2 : Heshen's Account Book Time Limit:1000ms Case Time Limit:1000ms Memory Limit:512MB Description H ...
- CodeForces 723F st-Spanning Tree
$dfs$,构造. 类似于$k$度限制生成树的想法,可以将$s$和$t$先从图中删去,将剩下的部分求连通块,每个连通块内部很容易构造生成树,每个连通块缩成一个点来处理. 连通块分三种: $1$.只与$ ...
- devops basic
- BZOJ 2323: [ZJOI2011]细胞
嗯..csdn发得出markdown了..请移步~ 个人觉得那个帅一点 嗯 好题啊!! 矩乘+DP 蒟蒻的我一开始发现了斐波那契数列之后就不会搞了.. 那个..什么质量相同两种方案相同就是扯淡的..想 ...
- 主数据及其管理MDM
什么是主数据 企业数据的管理包含主数据,元数据,交易数据. 主数据是描述企业核心实体的基础数据,比如客户.用户.产品.员工等. 它是具有高业务价值的.可以在企业内跨越各个业务部门被重复使用的数据,并且 ...
- hdu 5963 朋友(2016ccpc 合肥站 C题)
朋友 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submissi ...
- 【DFS】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem D. Divisibility Game
题意:给你一个序列,长度不超过52,每个元素不超过13.让你重新对这个序列排序,sum(i)表示i的前缀和,使得排序过后,对每个i,都有sum(i)%i==0. 深搜,加两个优化:①倒着从后向前搜:② ...
- [SimpleOJ239]Cards
题目大意: 有n(n为偶数)张牌,每张牌正反面有两张数字,你可以从中选出n/2张牌,减去某一面的数字,再选出另外n/2张牌,加上某一面的数字,问最终的答案最小能是多少? 思路: 先不考虑n/2的限制, ...
- 小H的硬币游戏
题目大意: 有n个物品排成一排,每个物品都有自己的价值,你每次可以从中挑选两个距离为k的物品取走,问最大的收益. (如果原来两个物品中间有物品被取走,距离不变) 思路: 贪心. 先按照每个物品的位置m ...
- Java并发(五):synchronized实现原理
一.synchronized用法 Java中的同步块用synchronized标记. 同步块在Java中是同步在某个对象上(监视器对象). 所有同步在一个对象上的同步块在同时只能被一个线程进入并执行操 ...