本文所有实例代码在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__的更多相关文章

  1. python 的__init__ 和__new__ 区别

    在此介绍一下  __init__ 和  __new__ 先后调用的区别 代码如下: # __init__ 和 __new__的区别 # 通常在编代码时,__init__ 较为常见,但是__new__却 ...

  2. Python中__init__和__new__的区别详解

    __init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- cod ...

  3. python中__init__()、__new__()、__call__()、__del__()几个魔法方法的用法

    关于__new__()的用法参考: http://www.myhack58.com/Article/68/2014/48183.htm 正文: 一.__new__()的用法: __new__()是在新 ...

  4. python中__init__()、__new__()、__call__()、__del__()用法

    关于__new__()的用法参考: http://www.myhack58.com/Article/68/2014/48183.htm 正文: 一.__new__()的用法: __new__()是在新 ...

  5. python中__init__和__new__的区别

    参考:https://my.oschina.net/liuyuantao/blog/747164 python中__metaclass的详解 参考:https://www.cnblogs.com/ia ...

  6. python中的__init__ 、__new__、__call__小结

    这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs)  创建对象时调用,返回 ...

  7. 详解python中的__init__与__new__方法

    一.__init__和__new__方法执行的顺序? 在面向对象中介绍了关于对象创建的过程,我们知道__new__方法先于__init__方法执行. 二.__new__方法是什么? 首先,我们先来看下 ...

  8. Python中的__init__和__new__

    一.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- c ...

  9. python中的__init__和__new__的区别

    一.__init__ 方法是什么?(init前后的线是双下划线) 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例 ...

随机推荐

  1. Codeforces 1104 D. Game with modulo-交互题-二分-woshizhizhang(Codeforces Round #534 (Div. 2))

    D. Game with modulo time limit per test 1 second memory limit per test 256 megabytes input standard ...

  2. hibernate对象关系映射的配置

    一对一主键关联单双向 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-m ...

  3. grunt-contrib-qunit安装过程中phantomjs安装报错问题解决

    今天自己fork了一个github上别人写的一个关于grunt项目的一个小demo(https://github.com/cowboy/jquery-tiny-pubsub),主要是想学习下grunt ...

  4. Ubuntu用户管理原理

    Ubuntu账户: Ubuntu有三类账户:超级用户.普通用户以及系统用户. 每一个用户在ubuntu中都必须拥有一种账户,在Ubuntu中, /etc/passwd用来保存每个账户的信息.实际密码保 ...

  5. Bomb Enemy -- LeetCode

    Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...

  6. JZYZOJ 1542 [haoi2015]str 矩阵乘法 dp

    http://172.20.6.3/Problem_Show.asp?id=1542 dp+矩阵乘法思路hin好想,对于我这种题目稍微学术就几乎什么也不会的人来说唯一的难点在于读题,因为一心想着划水题 ...

  7. [BZOJ 1901] Dynamic Rankings

    Link: BZOJ 1901 传送门 Solution: 带修改主席树的模板题 对于静态区间第$k$大直接上主席树就行了 但加上修改后会发现修改时复杂度不满足要求了: 去掉/增加第$i$位上的值时要 ...

  8. 【dijkstra】【次短路】【fread】hdu6181 Two Paths

    题意:给你一张简单无向图,问你1到n的次短路.注意,可以不是简单路径. 存个次短路板子,原理还是挺简单,直接看代码吧.然后这份代码还是个fread的示例用法. #include<cstdio&g ...

  9. 【并查集】Gym - 101128B - Black Vienna

    有26张牌(A~Z),其中三张被拿走了.其余23张被分发给了两个人.给你m次调查结果,一次调查结果是对其中一个人询问一对牌,他会告诉你他有这对牌的几张(0~2).问你有多少种被拿走的牌的组合. 三重循 ...

  10. python基础之数据类型,交互,格式化输出,基本运算符

    数据类型 1.什么是数据类型? 变量值才是我们存的数据,所以数据类型指的是变量值的种类 2.为何数据要分类? 变量值是用来保存现实世界中的状态的,那么针对不同的状态,就应该用不同类型的数据去表示 3. ...