27. python __new__ 深入探讨

python魔法函数

    • 一. __new__
    • 二. cls()函数

一. new

大家应该对__init__()方法都很熟悉,它的第一个参数一定是self,init()方法负责对象的初始化,系统执行该方法前,其实该实例对象已经存在,要不然初始化什么呢.通常来说,类开始实例化时,new()方法会返回cls(cls指代当前类)的实例,然后该类的__init__()方法会接收这个示例(即self)作为自己的第一个参数,然后依次转入__new__()方法中接收的位置参数和命名参数。

class Dog():def __new__(cls, *args, **kwargs):print("run the new of dog")#return super(Dog,cls).__new__(cls)return object.__new__(cls)  #两条return语句作用相同def __init__(self):print("run the init of dog")print(self)print(self.__class__)a = Dog()# run the new of dog
# run the init of dog
# <__main__.Dog object at 0x00000197AAA3A8D0>
# <class '__main__.Dog'>可以看出,1.当我实例化Dog类对象时,python中首先调用的是类对象的__new__()方法,如果该对象没有定义__new__()方法,则去父类中依次查找,直到object类(object类是所有类的基类哦)。
2. __new__()的返回语句中,object.__new__(cls)意思是调用父类(object)的__new__()super()是一个特殊函数,帮助python将父类和子类关联起来,父类也成超类,名称super因此得名。3. __new__()需要传递一个参数cls,__init__()需要传递一个参数self,self代表的就是实例对象本身,cls代表的是类对象本身。python中的self相当于C++的this指针。__new__()必须要有返回值,返回实例化出来的实例对象。
4.一般我们不会去重写__new__()方法,除非你确切知道怎么做,
什么时候你会去关心它呢,
它作为构造函数用于创建对象,是一个工厂函数,
专用于生产实例对象。著名的设计模式之一,
单例模式,就可以通过此方法来实现。

如果__new__()没有返回cls(即当前类的实例),那么当前类的__init__()方法是不会被调用的,如果__new__()返回了其他类的实例,那么只会调用被返回的那个类的构造方法。

class A(object):def __init__(self, *args, **kwargs):print("run the init of A")def __new__(cls, *args, **kwargs):print("run thr new of A")return object.__new__(B, *args, **kwargs)class B(object):def __init__(self):print("run the init of B")def __new__(cls, *args, **kwargs):print("run the new of B")return object.__new__(cls)a = A()
print(type(a))
# run thr new of A
# <class '__main__.B'>
b = B()
print(type(b))
# run the new of B
# run the init of B
# <class '__main__.B'>

其实__new__ 中的cls就是类本身,不是实例哦是类本身,下面看一个单例的实现:

# 实例化一个单例
class Singleton(object):__instance = Nonedef __new__(cls, age, name):#如果类数字__instance没有或者没有赋值#那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时#能够知道之前已经创建过对象了,这样就保证了只有1个对象if not cls.__instance:cls.__instance = object.__new__(cls)return cls.__instancedef __init__(self,age,name):self.age = ageself.name = name
a = Singleton(18, "wk")
b = Singleton(8, "mm")print(id(a)==id(b))
print(a.age,a.name)
print(b.age,b.name)
a.size = 19 #给a指向的对象添加一个属性
print(b.size)#获取b指向的对象的age属性# True
# 8 mm
# 8 mm
# 19对上面的代码优化下,只执行一次__init__:
# 实例化一个单例
class Singleton(object):__instance = None__first_init = Falsedef __new__(cls, age, name):if not cls.__instance:cls.__instance = object.__new__(cls)return cls.__instancedef __init__(self,age,name):if not self.__first_init:self.age = ageself.name = nameSingleton.__first_init = Truea = Singleton(18, "wk")
b = Singleton(8, "mm")print(id(a)==id(b))
print(a.age,a.name)
print(b.age,b.name)
a.size = 19 #给a指向的对象添加一个属性
print(b.size)#获取b指向的对象的age属性# True
# 18 wk
# 18 wk
# 19
  • init()通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性,做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
  • new()通常用于控制生成一个新实例的过程。它是类级别的方法。
  • new()至少有一个参数cls,代表要实例化的类,此参数在实例化时会有python编辑器自动提供。
  • new()必须有返回值,返回实例化出来的实例。
  • 如果将类比作制造商,new()方法发就是前期的原材料环节,init()方法就是在有了原材料的基础上,加工,初始化商品的环节。

二. cls()函数

class Demo(object):def __init__(self,name,age):self.name=nameself.age=ageprint('__init__() called...')def __new__(cls, name, age):""":type name: str"""print('__new__() - {cls}'.format(cls=cls))return object.__new__(cls)@classmethoddef bu(cls,name,age):return cls(name,age)if __name__ == '__main__':# de = Demo(age=0,name="999")# print(de.name)# print(de.age)s =  Demo.bu(name="张三", age=180)print(s.name)

cls(name, age) 实现了对 Demo 类的实例化,而 cls(name, age) 背后首先会调用 new 方法来创建对象,然后调用 init 方法来初始化对象

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

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

相关文章

linux下JDK的安装

前言&#xff1a; 安装部署java开发的代码都需要java环境&#xff0c;这里记录下linux下JDK的安装过程&#xff0c;仅供学习参考。 JDK的下载 下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads 选择和操作系统匹配的版本进行下载 查看操作系统&…

HarmonyOS NEXT学习——@BuilderParam装饰器

初步理解&#xff0c;相当于VUE的插槽slot Builder function overBuilder() {}Component struct Child {label: string ChildBuilder customBuilder() {}Builder customChangeThisBuilder() {}BuilderParam customBuilderParam: () > void this.customBuilder; // 使用自定…

人工智能未来发展前景将会怎样?

当我们探讨人工智能未来的发展前景时&#xff0c;可以从多个角度来详细说明其可能的影响和趋势&#xff1a; 技术进步与应用扩展 1.深度学习与机器学习&#xff1a; 进一步优化和算法进展&#xff1a;深度学习已经取得了巨大成就&#xff0c;但仍面临挑战&#xff0c;如对小数…

浅说区间dp(下)

文章目录 环形区间dp例题[NOI1995] 石子合并题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 [NOIP2006 提高组] 能量项链题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 [NOIP2001 提高组] 数的划分题目描述输入格式输出格式样例 #1样例输…

你也许不知道,自己可能是一个「热人」

稍微标题党了一下。: ) 今天想跟大家分享的&#xff0c;是一种很少有人了解的人格特质。它非常普遍&#xff0c;许多人都或多或少有一些倾向&#xff0c;但却很少有人意识到它。 不妨看一看&#xff0c;你有没有下面这些特征&#xff1a; 有着极其旺盛的求知欲&#xff0c;对许…

C++函数(函数原型,指标、参考、预设、可变参数)第一部

函数原型 自订函数的定义需要放在main()或呼叫之前&#xff0c;如果放在main()或呼叫之后&#xff0c;例如 #include <iostream>int main() {do_something("Whats truth?");do_something("There is no spoon.");return 0; }void do_something(cha…

paddleocr icdar2015数据集训练dbnet检测模型

参考&#xff1a;https://github.com/PaddlePaddle/PaddleOCR/blob/main/doc/doc_ch/detection.md 原理 DBNET论文 Real-time Scene Text Detection with Differentiable Binarization 参考&#xff1a;https://blog.csdn.net/qq_35756383/article/details/118679258 Real-T…

7,SSH scp 命令

scp 命令 scp是 SSH 提供的一个客户端程序&#xff0c;用来在两台主机之间加密传送文件&#xff08;即复制文件&#xff09;。 简介 scp是 secure copy 的缩写&#xff0c;相当于cp命令 SSH。它的底层是 SSH 协议&#xff0c;默认端口是22&#xff0c;相当于先使用ssh命令登…

【STC89C51单片机】定时器/计数器的理解

目录 定时器/计数器1. 定时器怎么定时简单理解&#xff08;加1经过了多少时间&#xff09;什么是时钟周期什么是机器周期 2.如何设置定时基本结构相关寄存器1. TMOD寄存器2. TCON寄存器 代码示例 定时器/计数器 STC89C51单片机的定时器和计数器&#xff08;Timers and Counter…

【BUG】已解决:NameError: name ‘XXX‘ is not defined

已解决&#xff1a;NameError: name ‘XXX‘ is not defined 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发者社…

Harmony 状态管理 @Local 和 @Param

Harmony 状态管理 Local 和 Param Local 背景 Local 是harmony应用开发中的v2版本中 对标**State**的状态管理修饰器&#xff0c;它解决了 State 对状态变量更改的检测混乱的问题&#xff1a; State 修饰的状态变量 可以是组件内部自己定义的State 修饰的状态 也可以由外部父…

路径规划 | 基于DQN深度强化学习算法的路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 DQN路径规划算法 基于深度强化学习算法的路径规划 matlab2023b 栅格环境&#xff0c;走迷宫&#xff0c;可以通过窗口界面方便观察交互过程&#xff0c;代码注释详尽。 程序设计 完整源码和数据私信博主回复基于DQN深…

Vue学习---vue cli 项目创建

使用的编辑工具webStorm 创建例子: hello vue create hello 选择 vue3 进行创建 运行 npm run serve 测试访问&#xff1a;http://localhost:8080 改动内容重新编译&#xff1a; npm run build dist 目录就是编译后的可运行内容

1分钟带你了解苹果手机删除照片恢复全过程

在日常使用苹果手机时&#xff0c;我们可能会不小心删除掉一些重要的照片&#xff0c;这让人非常烦恼。那么苹果手机怎么恢复删除的照片&#xff1f;下面小编将会向大家介绍苹果手机恢复删除的照片的方法&#xff0c;帮助大家轻松找回你丢失的照片。 一、利用“最近删除”文件夹…

ChatGPT:为什么计数排序需要进行累加操作

ChatGPT&#xff1a;为什么计数排序需要进行累加操作 第一种写法 private static void countSort() {int[] MaxMin findMaxMin();int max MaxMin[0];int min MaxMin[1];int[] counts new int[max - min 1];for (int num : nums) {counts[num - min];}int index 0;for (i…

甲骨文面试题【动态规划】力扣377.组合总和IV

给你一个由 不同 整数组成的数组 nums &#xff0c;和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3], target 4 输出&#xff1a;7 解释&#x…

【Linux】详解加锁实现线程互斥

一、多线程不加线程互斥可能会引发的问题 下面是一个抢标逻辑。抢票为什么会抢到负数&#xff1a;假设当票数为1时&#xff0c;此时四个进程的判断条件tickets都大于0&#xff0c;都会进入抢票操作&#xff0c;第一个进程抢完票以后tickets0并写回内存&#xff0c;第二个进程再…

Xcode进行真机测试时总是断连,如何解决?

嗨。大家好&#xff0c;我是兰若姐姐。最近我在用真机进行app自动化测试的时候&#xff0c;经常会遇到xcode和手机断连&#xff0c;每次断连之后需要重新连接&#xff0c;每次断开都会出现以下截图的报错 当这种情况出现时&#xff0c;之前执行的用例就相当于白执行了&#xff…

Adobe XD中文设置指南:专业设计师的现场解答

Adobe XD是世界领先的在线合作UI设计工具。它摆脱了Sketch、Figma等传统设计软件对设备的依赖&#xff0c;使设计师可以随时随地使用任何设备打开网页浏览器&#xff0c;轻松实现跨平台、跨时空的设计合作。然后&#xff0c;为了提高国内设计师的使用体验&#xff0c;Adobe XD如…

爬虫(二)——爬虫的伪装

前言 本文是爬虫系列的第二篇文章&#xff0c;主要讲解关于爬虫的简单伪装&#xff0c;以及如何爬取B站的视频。建议先看完上一篇文章&#xff0c;再来看这一篇文章。要注意的是&#xff0c;本文介绍的方法只能爬取免费视频&#xff0c;会员视频是无法爬取的哦。 爬虫的伪装 …