Python __new__()方法详解
一般情况下,覆写 __new__() 的实现将会使用适的参数调用其超类的 super().__new__(),并在返回之前修改实例。例如:
class demoClass:
instances_created = 0
def __new__(cls,*args,**kwargs):
print("__new__():",cls,args,kwargs)
instance = super().__new__(cls)
instance.number = cls.instances_created
cls.instances_created += 1
return instance
def __init__(self,attribute):
print("__init__():",self,attribute)
self.attribute = attribute
test1 = demoClass("abc")
test2 = demoClass("xyz")
print(test1.number,test1.instances_created)
print(test2.number,test2.instances_created)
输出结果为:
__new__(): <class '__main__.demoClass'> ('abc',) {}
__init__(): <__main__.demoClass object at 0x0000026FC0DF8080> abc
__new__(): <class '__main__.demoClass'> ('xyz',) {}
__init__(): <__main__.demoClass object at 0x0000026FC0DED358> xyz
0 2
1 2
__new__() 通常会返回该类的一个实例,但有时也可能会返回其他类的实例,如果发生了这种情况,则会跳过对 __init__() 方法的调用。而在某些情况下(比如需要修改不可变类实例(Python 的某些内置类型)的创建行为),利用这一点会事半功倍。比如:
class nonZero(int):
def __new__(cls,value):
return super().__new__(cls,value) if value != 0 else None
def __init__(self,skipped_value):
#此例中会跳过此方法
print("__init__()")
super().__init__()
print(type(nonZero(-12)))
print(type(nonZero(0)))
运行结果为:
__init__()
<class '__main__.nonZero'>
<class 'NoneType'>
那么,什么情况下使用 __new__() 呢?答案很简单,在 __init__() 不够用的时候。
例如,前面例子中对 Python 不可变的内置类型(如 int、str、float 等)进行了子类化,这是因为一旦创建了这样不可变的对象实例,就无法在 __init__() 方法中对其进行修改。
有些读者可能会认为,__new__() 对执行重要的对象初始化很有用,如果用户忘记使用 super(),可能会漏掉这一初始化。虽然这听上去很理,但有一个主要的缺点,即如果使用这样的方法,那么即便初始化过程已经是预期的行为,程序员明确跳过初始化步骤也会变得更加困难。不仅如此,它还破坏了“__init__() 中执行所有初始化工作”的潜规则。
注意,由于 __new__() 不限于返回同一个类的实例,所以很容易被滥用,不负责任地使用这种方法可能会对代码有害,所以要谨慎使用。一般来说,对于特定问题,最好搜索其他可用的解决方案,最好不要影响对象的创建过程,使其违背程序员的预期。比如说,前面提到的覆写不可变类型初始化的例子,完全可以用工厂方法(一种设计模式)来替代。
Python中大量使用 __new__() 方法且理的,就是 MetaClass 元类。有关元类的介绍,可阅读《Python MetaClass元类》一节。
- 随机文章
- 港丽 马尔代夫 特点(探秘马尔代夫得天独厚的海岛风光与奢华旅游体验)
- 中国西沙马尔代夫(中国和马尔代夫联合进行西沙海域演练)
- 中国飞抵马尔代夫(中国航班抵达马尔代夫,开启旅游之旅)
- 呐喊来到马尔代夫(呐喊告诉你,马尔代夫已经准备好了!)
- 宜兴马尔代夫介绍(探寻宜兴度假胜地:仿若身处马尔代夫)
- 基友 马尔代夫(重新诠释:与兄弟们同赏 马尔代夫完美之旅)
- 头像马尔代夫旅游(体验马尔代夫,世外桃源般的旅游胜地)
- 宜昌马尔代夫地图(快速了解宜昌一日游马尔代夫岛屿地图)
- 化妆视频马尔代夫(在马尔代夫看到自然美 ——化妆视频)
- 描写马尔代夫美景(「重温马尔代夫:探索绝美海底世界」)
- 太原 马尔代夫(山城梦幻岛:太原市民自建泳池 营造马尔代夫风情)
- 水城龙场马尔代夫(水城龙场团队揭秘马尔代夫旅行小贴士)
- 旅游马尔代夫价位(马尔代夫旅游:预算范围内的美丽天堂)
- 平乐阳安马尔代夫(探访马尔代夫平乐阳安,探寻当地魅力)
- 湖北荆门马尔代夫(湖北荆门现实版马尔代夫,美如天堂!)
- 奥静 马尔代夫(奥静集团进驻马尔代夫扩大海外投资)
- 环球日记马尔代夫(马尔代夫游记——纯净海滩与无限阳光)
- 漳州马尔代夫位置(漳州市首家模拟马尔代夫度假村落地!)
- 儿童马尔代夫发烧(儿童马尔代夫出现高烧,紧急送医治疗)
- 悉尼直飞马尔代夫(直飞马尔代夫,探访印度洋里的天堂!)
- 萍乡马尔代夫介绍(萍乡游客必看:探究马尔代夫岛国风情)
- 深度介绍马尔代夫(探索马尔代夫:天堂之岛的美丽和魅力)
- 洛阳马尔代夫现状(洛阳市伊川县水库变成马尔代夫风景区)
- 翡翠马尔代夫玫瑰(马尔代夫玫瑰:翡翠开辟全新度假天堂)
- 韩国马尔代夫蜜月(韩国新婚夫妇选择前往马尔代夫度蜜月)
- 澳门 马尔代夫(后的:两个亚洲旅游胜地:澳门 vs. 马尔代夫)
- 重庆地区马尔代夫(重庆限时特惠:疫情后的马尔代夫之旅)
- 洛阳马尔代夫钓鱼(洛阳打造“马尔代夫钓鱼”旅游新热点)
- 英国女王马尔代夫(英国女王访问马尔代夫,强化两国关系)
- 郑智 马尔代夫(郑智领衔广州恒大赴马尔代夫备战新赛季)
