python基础之__new__的用法介绍

今天介绍下__new__的用法:

__new__是新式类中出现,是一种静态方法。在python官方文档中,介绍了在那些情况下可以使用:
Use __new__ when you need to control the creation of a new instance. Use __init__ when you need to control initialization of a new instance.
__new__ is the first step of instance creation. It's called first, and is responsible for returning a new instance of your class. In contrast, __init__ doesn't return anything; it's only responsible for initializing the instance after it's been created.
In general, you shouldn't need to override __new__ unless you're subclassing an immutable type like str, int, unicode or tuple.
链接:https://docs.python.org/3/reference/datamodel.html?highlight=__new__#object.__new__有兴趣的可以查看官方文档。它和__init__被放基本定制章节,主要用于类实例的定制化。

从上面英文的意思,可以知道:
  • 需要控制实例的创建的时候,使用__new__;在类创建过程中,最先调用并返回类实例;
  • 在实例已经被创建出来的时候,当需要实例初始化的时候,使用__init__;
  • 一般来说,不建议重写__new__,除非是在构建str,int,unincode或者tuple不可变类型的子类的时候
从中可以看出,__new__负责对象的创建,__init__负责对象的初始化,因此__new__的过程在__init__之前。
__new__的定义:
def __new__(cls,*args,**kwargs):
pass
参数说明:cls指当前正在实例化的类
根据__new__定义我们可以设计以下几种实验场景:
1)返回该类本身创建实例
class clsA(object):
def __new__(cls, *args, **kwargs):
print('A')
print(cls)
print(clsA)
return object.__new__(cls,*args,**kwargs)

def __init__(self):
print('A.__init__')
print(clsA())
输出结果是:
A
<class '__main__.clsA'>
<class '__main__.clsA'>
A.__init__
<__main__.clsA object at 0x05170270>
从第一个例子中,我们可以看出,参数cls和clsA等价

2)返回另一个类的实例
class clsB(object):
def __new__(cls, *args, **kwargs):
return clsA.__new__(clsA,*args,**kwargs)
def __init__(self):
print('clsB.__init__')
print(clsB())
输出结果是:
A
<class '__main__.clsA'>
<class '__main__.clsA'>
<__main__.clsA object at 0x056C0430>
从第二个例子中看出,打印出了clsA中__new__输出的东西,并没有执行clsB.__init__;这是因为clsB没有成功的创建clsB的实例,那么clsB.__init__没有可接收的self对象,当然无法执行了。

3)__new__没有return的情况
class clsC(object):
def __new__(cls, *args, **kwargs):
print('clsC.__new__')
def __init__(self):
print('clsC.__init__')

print(clsC())
输出结果是:
clsB.__new__
None
从第三个例子,可以看出clsC没有返回对象时,__init__是不执行的,并且打印对象的信息也是None,因为没有创建实例对象。

最后说下,__new__和__init__不是必须写的,没有它们的会直接继承Object的。

猜你喜欢

转载自blog.csdn.net/mucangmang/article/details/79599251
今日推荐