首页 > 编程语言 >Python __new__()方法详解

Python __new__()方法详解

时间:2022-10-17 21:48:43浏览次数:80  
标签:__ Python init print new cls

__new__() 是一种负责创建类实例的静态方法,它无需使用 staticmethod 装饰器修饰,且该方法会优先 __init__() 初始化方法被调用。

一般情况下,覆写 __new__() 的实现将会使用合适的参数调用其超类的 super().__new__(),并在返回之前修改实例。例如:

  1. class demoClass:
  2. instances_created = 0
  3. def __new__(cls,*args,**kwargs):
  4. print("__new__():",cls,args,kwargs)
  5. instance = super().__new__(cls)
  6. instance.number = cls.instances_created
  7. cls.instances_created += 1
  8. return instance
  9. def __init__(self,attribute):
  10. print("__init__():",self,attribute)
  11. self.attribute = attribute
  12. test1 = demoClass("abc")
  13. test2 = demoClass("xyz")
  14. print(test1.number,test1.instances_created)
  15. 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 的某些内置类型)的创建行为),利用这一点会事半功倍。比如:
  1. class nonZero(int):
  2. def __new__(cls,value):
  3. return super().__new__(cls,value) if value != 0 else None
  4. def __init__(self,skipped_value):
  5. #此例中会跳过此方法
  6. print("__init__()")
  7. super().__init__()
  8. print(type(nonZero(-12)))
  9. 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元类》一节。

标签:__,Python,init,print,new,cls
From: https://www.cnblogs.com/qlsh/p/16800781.html

相关文章

  • P4310 绝世好题
    题意:给出n个数,求最长子序列(不是子数组)的长度,使得其与运算的结果不为0。解:位运算的好处是和顺序无关。第一想法是找每一位为1的最多有几个数。但考虑3,7这种二进制下全是1的......
  • FedEx api获取token
     usingMicrosoft.AspNetCore.Mvc;usingRestSharp;usingSystem.Net;usingSystem.Text;usingNewtonsoft.Json;   publicstringFed_GetAccessToken()......
  • Spring boot 嵌入式容器的运行参数配置 server properties调优、为Web Server配置Http
        serverproperties           配置Https jdk/bin目录下keytool         访问http时,跳转到https ......
  • IOC 生命周期-服务范围
    publicclassServicesPrpvoder:IServicesPrpvoder服务提供者可以利用IserviceScoprFactory创建一个服务范围IServiceScope对象IServicesScope的包含IServicesPrpvod......
  • Python导入模块,Python import用法(超级详细)
    使用 Python 进行编程时,有些功能没必须自己实现,可以借助Python现有的标准库或者其他人提供的第三方库。比如说,在前面章节中,我们使用了一些数学函数,例如余弦函数cos()......
  • Codeforces Round #827 (Div. 4) 复盘+题解
    原比赛链接复盘:ABC签到,手速太慢了。D捣鼓了好久才想起来从更小的值域出发去做。E简单二分答案。然后就timeout了。D题搞错方向浪费太久时间了。F思维题,拐两个弯再$r......
  • javaweb实操之session'
    什么是session服务器会给一个用户(浏览器)创建一个session对象一个session独占一个浏览器,只要浏览没有关闭,这个session就存在用户登录之后,整个网站都可以访问->保存用......
  • 什么是文件路径,Python中如何书写文件路径?
    当程序运行时,变量是保存数据的好方法,但变量、序列以及对象中存储的数据是暂时的,程序结束后就会丢失,如果希望程序结束后数据仍然保持,就需要将数据保存到文件中。Python 提......
  • 基于深度学习的人脸识别系统——原理篇
    1.深度学习的基本原理深度学习的起源最早可以追溯到感知机,所谓的感知机即只有一个神经元的单层神经网络,它只能完成一个简单的线性分类任务,而要解决非线性的任务,一是......
  • Selenium4Web自动化2-页面元素定位
    一前端页面的组成分析详解1常见标签标签语言,常见的标签有:a:超链接img:图片input:输入框、文件上传button:按钮select:下拉框iframe:窗体p:文字。。。。。2标签语......