详解Python的__new__()方法

__new____init__的区别
new() 方法主要存在于Python2的新式类和Python3中。它是负责创建类实例的静态方法。
当Python实例化一个对象时,首先调用__new__()方法构造一个类的实例,并为其分配对应类型的内存空间,该实例的内存地址就是它的唯一标识符。然后再调用__init__()方法对实例进行初始化,通常是对该实例的属性进行初始化。
以下用几个实例来说明:
实例1:先调用__new__()方法再调用__init__()方法

class Person(object):def __new__(cls):print("__new__ called")return super().__new__(cls)def __init__(self):print("__init__ called")a = Person()'''
__new__ called
__init__ called
'''

实例2:new()方法构造一个类实例,并将该实例传递给自身的__init__()方法,即__init__()方法的self参数。

class Person(object):def __new__(cls):print("__new__ called")instance = super().__new__(cls)print(type(instance))print(instance)print(id(instance))return instancedef __init__(self):print("__init__ called")print(id(self))b = Person()'''
__new__ called
<class '__main__.Person'>
<__main__.Person object at 0x1093c1580>
4449899904
__init__ called
4449899904
'''

实例3:如果__new__()方法不返回任何实例的话,init()方法将不会被调用。

class Person(object):def __new__(cls):print("__new__ called")def __init__(self):print("__init__ called")c = Person()'''
__new__ called
'''

实例4:如果__new__()方法返回一个其他类的实例的话,那它自身的__init__()方法将不会被调用。而且,new()方法将会初始化一个其他类的对象。

class Animal(object):def __init__(self):passclass Person(object):def __new__(cls):print("__new__ called")return Animal()def __init__(self):print("__init__ called")d = Person()
print(type(d))
print(d)'''
__new__ called
<class '__main__.Animal'>
<__main__.Animal object at 0x10fea3550
'''

实例5:如果重写__new__()方法时,除了cls参数外不再设置其他参数的话,将无法用__init__()方法来设置初始化参数。

class Person(object):def __new__(cls):print("__new__ called")instance = super().__new__(cls)return instancedef __init__(self, name):print("__init__ called")self.name = namee = Person("Eric")
print(e.name)'''
Traceback (most recent call last):File "example.py", line 102, in <module>e = Person("Eric")
TypeError: __new__() takes 1 positional argument but 2 were given
'''

实例6:在重写__new__()方法时,需要在参数中加入*args,**kwargs,或者显式地加入对应的参数,才能通过__init__()方法初始化参数。

class Person(object):def __new__(cls, *args,**kwargs):  # Or def __new__(cls, name)print("__new__ called")instance = super().__new__(cls)return instancedef __init__(self, name):print("__init__ called")self.name = namee = Person("Eric")
print(e.name)'''
__new__ called
__init__ called
Eric
'''
  • __init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值。
  • __init__必须有一个参数self,这个是__new__的返回值, __init__不需要返回值
  • __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。
  • new 至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
  • new 的参数除了cls外要有和实例化类给出的参数数量一致
  • __new__也可以设置对象属性(如果init重新设置了对象属性那么将被覆盖)
  • self代表的是类的实例,而cls则代表的是类本身
    __new__的运用场景
  • 允许继承不可变类型(str,int, tuple)
  • 实现单例设计模式

允许继承不可变类型

当我们需要继承内置类时,例如,想要继承 int、str、tuple,就无法使用 __init__ 来初始化了,只能通过__new__来初始化数据。
实例1:这个类继承了 float,之后就可以对这个类的实例进行计算了。

class g(float):"""千克转克"""def __new__(cls, kg):return float.__new__(cls, kg * 2)a = g(50) # 50千克转为克
print(a) 	# 100
print(a + 100)	# 200 由于继承了float,所以可以直接运算,非常方便!

实例2:这个类继承了int,用__new__来生成一个正数的类。

class PositiveInteger(int):def __new__(cls,value):return super(PositiveInteger,cls).__new__(cls,abs(value))def __init__(self,value):super(PositiveInteger,self).__init__()c = PositiveInteger(-1)
print(c) #打印出1

实现单例设计模式

单例设计模式是为了解决一个类有多个对象的时候,多个对象引用同一个内存地址,以减少内存占用的问题。实现思路:重写父类的__new__方法,使每次返回的内存地址引用都为同一个。

class Singleton(object):boolean = Nonedef __new__(cls):if cls.boolean == None:cls.boolean = super().__new__(cls)return cls.booleanc1 = Singleton()
c2 = Singleton()
print(c1)
print(c2)'''
<__main__.Singleton object at 0x02485670>
<__main__.Singleton object at 0x02485670>
'''

可以看出我们创建了两个实例,并且返回的内存都是一样的,这避免了内存的重复占用。

参考网址
https://blog.csdn.net/abigdream984/article/details/118001379
https://www.cnblogs.com/luocodes/p/10723778.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/85843.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

科目二倒车入库

调整座位和后视镜 离合踩到底大腿小腿成130-140 上半身90-100 座椅高度能看到前方全部情况 后视镜调节到能看到后门把手&#xff0c;且后门把手刚好在后视镜上方边缘、离车1/3处。 保持直线&#xff1a; 前进&#xff1a; 车仪表盘中央的原点和地面上的黄线擦边&#xff…

Docker CMD指令如何覆写

在Dockerfile里,CMD指令是可以被覆盖的。 在构建镜像时,可以通过docker build命令的–cmd选项覆盖Dockerfile的CMD: 例如: FROM ubuntu CMD ["echo","hello"]构建时覆盖CMD: docker build -t test --cmd "echo world" .在创建容器时,可以通过…

【AI视野·今日NLP 自然语言处理论文速览 第三十八期】Thu, 21 Sep 2023

AI视野今日CS.NLP 自然语言处理论文速览 Thu, 21 Sep 2023 Totally 57 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Chain-of-Verification Reduces Hallucination in Large Language Models Authors Shehzaad Dhuliawala, Mojt…

PyTorch深度学习实战(17)——多任务学习

PyTorch深度学习实战&#xff08;17&#xff09;——多任务学习 0. 前言1. 多任务学习1.1 多任务学习基本概念1.2 多任务学习优势 2. 模型与数据集分析2.1 模型分析2.2 数据集介绍 3. 实现年龄估计和性别分类小结系列链接 0. 前言 多任务学习( Multi-Task Learning, MTL )是一…

双向控制舵机(树莓派版)

文章目录 前言1、舵机参数2、功能测试参考文献 前言 为了实现垃圾分类和倾倒功能&#xff0c;于是购买了180度舵机 避坑提示&#xff1a;360度舵机无法像180度舵机一样控制角度&#xff0c;它只能控制旋转方向和速度&#xff0c;所以别买360度的舵机。 1、舵机参数 我买的舵机…

ajax上传文件

背景 采用ajax传递表单内容和上传的文件 实现原理 使用FormData模拟表单数据&#xff0c;实现异步上传图片 代码 var formData new FormData(); formData.append("serviceId", param.serviceId); formData.append("keyId", param.keyId); formData.a…

194、SpringBoot -- 下载和安装 Erlang 、 RabbitMQ

本节要点&#xff1a; 一些命令&#xff1a; 小黑窗输入&#xff1a; rabbitmq-plugins enable rabbitmq_management 启动控制台插件 rabbitmq-server 启动rabbitMQ服务器 管理员启动小黑窗&#xff1a; rabbitmq-service install 添加rabbitMQ为本地服务 启动浏览器访问“h…

ffmpeg ffplay

gif -> jpg: ffmpeg -i 4.gif -r 25 -q:v 4 -pix_fmt yuv420p jpg2/frame%03d.jpg -y # ffplay ffplay [选项] [输入文件] option -x width 强制以 "width" 宽度显示 -y height 强制以 "height" 高度显示 -an 禁止音频 …

gym_unity学习笔记

最近学了一段时间gym_unity&#xff0c;把一些资料留在这里 实例 实例gym_unity训练RollerBall&#xff1a;https://blog.csdn.net/alibutter/article/details/120908687实例gyn_unity训练3DBall&#xff1a;https://zhuanlan.zhihu.com/p/554927641?utm_id0 源码&#xff1…

大二毕设.3-网盘系统-用户模块讲解

目录 模块功能介绍 具体实现讲解 constants层&#xff1a;存放用户模块常量类 entity层&#xff1a;存放实体类&#xff0c;与数据库中的属性值基本保持一致 mapper层&#xff1a;对数据库进行数据持久化操作 service层&#xff1a;业务逻辑层&#xff0c;主要是针对具体…

基于香橙派和SU-03T 使用Linux实现语音控制刷抖音

硬件介绍 SU-03T之前在小车的时候使用过&#xff0c;详见&#xff1a;语音小车---6 最终整合_mjmmm的博客-CSDN博客 按照下图进行接线&#xff1a; 项目需求 通过语音指令来控制安卓手机刷抖音&#xff0c;可以实现视频切换和点赞等功能&#xff1a; 1. 开机播报“你好&a…

Go 并发可视化解释 - sync.Mute

在学习 Go 编程语言时&#xff0c;您可能会遇到这句著名的格言&#xff1a;“不要通过共享内存来进行通信&#xff1b;相反&#xff0c;通过通信来共享内存。” 这句话构成了 Go 强大并发模型的基础&#xff0c;其中通道&#xff08;channels&#xff09;作为协程之间的主要通信…

6条优势,anzo capital昂首资本相信MT5替代MT4的原因

投资者都知道MT5是在MT4基础上升级换代的多资产平台&#xff0c;MT5于2010年6月首次发布。anzo capital昂首资本认为MT5将完全取代MT4&#xff0c;就像MT4取代之前版本一样&#xff0c;因为有以下6条优势&#xff1a; 一.市场深度(DOM)数据。在MT4中&#xff0c;DOM几乎没有用…

什么是生成对抗网络 (GAN)?

什么是生成对抗网络 &#xff08;GAN&#xff09;&#xff1f; 钦吉兹赛义德贝利 一、说明 GAN&#xff08;Generative Adversarial Network&#xff09;网络是一种深度学习模型&#xff0c;由两个神经网络——生成器和判别器组成。生成器负责生成虚假的数据&#xff0c;而判别…

yarn安装依赖时报错 error An unexpected error occurred:

一切起因是因为前一天安装了volta管理node&#xff0c;第二天启动项目&#xff0c; 显示error An unexpected error occurred: “https://registry.npmmirror.com/webpack-aliyun-oss/-/webpack-aliyun-oss-0.2.6.tgz: Request failed “404 Not Found””. 项目启动时发现报错…

【WSN】基于蚁群算法的WSN路由协议(最短路径)消耗节点能量研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

在 SQL Server 中,可以使用内置函数 NEWID() 来生成一个随机的 GUID(全局唯一标识符)。可以将此 GUID 作为字符串拼接到查询结果中。

以下是一个示例&#xff1a; SELECT Column1, Column2, CAST(NEWID() AS VARCHAR(36)) as random_string FROM your_table;这将在查询结果中添加一个名为 random_string 的列&#xff0c;其中包含一个随机生成的 GUID。请注意&#xff0c;由于 GUID 是随机生成的&#xff…

MySQL学习系列(9)-每天学习10个知识

目录 1. 临时表&#xff08;Temporary Tables&#xff09;的优点和缺点2. 使用GROUP BY进行聚合查询3. MySQL的索引设计4. NULL和默认值的区别和用途5. 使用LIKE和REGEXP进行模式匹配6. SQL标准的三个范式7. 视图和有效性约束8. 自连接&#xff08;Self Join&#xff09;的场景…

【虚拟化】虚拟机vcpu绑核物理机

文章目录 一、NUMA二、虚拟机xml配置解析 参考文章 第一篇&#xff1a;KVM虚拟化CPU技术总结 第二篇&#xff1a;虚机cpu和mem的配置&#xff08;cputune和numatune&#xff09; 第三篇&#xff1a;libvirt 中cpu, numa 的配置 第四篇&#xff1a;如何提高虚拟机性能&#xff1…

安全学习_开发相关_JavaEE过滤器监听器简单了解

文章目录 Web应用运行流程图 JavaEE-过滤器-Filter过滤器概述&作用过滤器相关安全测试场景 JavaEE-监听器-Listener监听器作用&#xff1a;监听器相关安全测试场景 过滤器和监听器&#xff0c;主要对安全测试有影响的是过滤器&#xff0c;监听器只是在对代码进行逻辑分析时…