python中的魔法方法__new___python魔法方法,详解__new__()和__init__()

魔法方法__new__()和__init__()真是困扰了我好久。其实就是对__new__()一直不是很理解。今天做一个小小的总结吧,在这个知识点上真是花了太久的时间了。

首先回顾一下类与对象

python中一切皆为对象,python类本身也是一种对象,我们可以称其为类对象。对象=属性+方法,对象是类的实例,准确地来说,应该是:实例对象是类对象的实例。

《python编程:从入门到实践》中是这么说的:面向对象编程是最有效的软件编写方法之一。在面向对象编程中,你编写表示现实世界的实物和情景的类,定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动兼备这种通用行为,然后可根据需要赋予每个对象独特的个性。根据类创建对象被称为实例化,这让你能够使用类的实例。end

类主要是定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,还包含所有实例共享的数据。

接下来,进入正题。

大家应该对__init__()方法都很熟悉,它的第一个参数一定是self,__init__()方法负责对象的初始化,系统执行该方法前,其实该实例对象已经存在,要不然初始化什么呢,

先看一小段代码:

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>

#

可以看出,当我实例化Dog类对象时,python中首先调用的是类对象的__new__()方法,如果该对象没有定义__init__()方法,则去父类中依次查找,直到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. 看一下阿里云天池python训练营对这两个魔法方法的教学:__new__(cls[, ...]) 是在一个对象实例化的时候所调用的第一个方法,在调用__init__初始化前,先调用__new__。

__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给__init__。

__new__对当前类进行了实例化,并将实例返回,传给__init__的self。但是,执行了__new__,并不一定会进入__init__,只有__new__返回了,当前类cls的实例,当前类的__init__才会进入。

若__new__没有正确返回当前类cls的实例,那__init__是不会被调用的,即使是父类的实例也不行,将没有__init__被调用。

__new__方法主要是当你继承一些不可变的 class 时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。

一般我们不会去重写__new__()方法,除非你确切知道怎么做,什么时候你会去关心它呢,它作为构造函数用于创建对象,是一个工厂函数,专用于生产实例对象。著名的设计模式之一,单例模式,就可以通过此方法来实现。

在自己写框架级的代码时,可能你会用到它,我们也可以从开源代码中找到它的应用场景,例如微型 Web 框架 Bootle 就用到了。

再来看几个例子。

通常来说,类开始实例化时,__new__()方法会返回cls(cls指代当前类)的实例,然后该类的__init__()方法会接收这个示例(即self)作为自己的第一个参数,然后依次转入__new__()方法中接收的位置参数和命名参数。

notice:如果__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

#

b = B()

print(type(b))

# run the new of B

# run the init of B

#

这个例子也是参考网上,自己修改的。感觉这个例子明白后,对__new__()的理解就差不多了。

接下来,看一下单例模式。单例模式是什么

举个常见的单例模式例子,我们日常使用的电脑上都有一个回收站,在整个操作系统中,回收站只能有一个实例,整个系统都使用这个唯一的实例,而且回收站自行提供自己的实例。因此回收站是单例模式的应用。

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象创建型模式。

2. 创建单例-保证只有一个对象

# 实例化一个单例

class Singleton(object):

__instance = None

def __new__(cls, age, name):

#如果类数字__instance没有或者没有赋值

#那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时

#能够知道之前已经创建过对象了,这样就保证了只有1个对象

if not cls.__instance:

cls.__instance = object.__new__(cls)

return cls.__instance

def __init__(self,age,name):

self.age = age

self.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

3. 创建单例,只执行一次__init__()方法。

# 实例化一个单例

class Singleton(object):

__instance = None

__first_init = False

def __new__(cls, age, name):

if not cls.__instance:

cls.__instance = object.__new__(cls)

return cls.__instance

def __init__(self,age,name):

if not self.__first_init:

self.age = age

self.name = name

Singleton.__first_init = True

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

# 18 wk

# 18 wk

# 19

奇妙!基本ok了。

总结下__init__()和__new__()的区别:__init__()通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性,做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。

__new__()通常用于控制生成一个新实例的过程。它是类级别的方法。

__new__()至少有一个参数cls,代表要实例化的类,此参数在实例化时会有python编辑器自动提供。

__new__()必须有返回值,返回实例化出来的实例。

如果将类比作制造商,__new__()方法发就是前期的原材料环节,__init__()方法就是在有了原材料的基础上,加工,初始化商品的环节。

其他的魔法方法得再写一篇文章了,真是参考了大量网上的例子,真诚感谢前人们的博客、文章。

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

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

相关文章

王喜文:图解新基建,细说新机遇(100图)

来源&#xff1a;智造智库去年8月22日&#xff0c;华为创始人任正非签发总裁办邮件&#xff0c;大力推荐技术大神王喜文博士的5G科普PPT《认识5G&#xff0c;发展5G》&#xff0c;并报送董事会成员、监事会成员&#xff0c;主送全体员工&#xff0c;要求华为全员学习。任正非的…

基于OpenGL编写一个简易的2D渲染框架-07 鼠标事件和键盘事件

这次为程序添加鼠标事件和键盘事件 当检测到鼠标事件和键盘事件的信息时&#xff0c;捕获其信息并将信息传送到需要信息的对象处理。为此&#xff0c;需要一个可以分派信息的对象&#xff0c;这个对象能够正确的把信息交到正确的对象。 实现思路&#xff1a; 要实现以上的功能&…

重新定义Wi-Fi功能,Wi-Fi 6为什么要分两步?

来源&#xff1a;传感器技术Wi-Fi 6重新定义Wi-Fi&#xff0c;先是双频并发&#xff0c;然后才是6GHz下的160MHz。Wi-Fi是什么&#xff1f;它是一个基于IEEE 802.11标准的无线局域网技术。如今&#xff0c;Wi-Fi已经覆盖了绝大部分的室内场景&#xff0c;你的手机、电脑、智能音…

python爬虫系统实验报告问题的分析_Python爬虫总结——常见的报错、问题及解决方案...

在爬虫开发时&#xff0c;我们时常会遇到各种BUG各种问题&#xff0c;下面是我初步汇总的一些报错和解决方案。在以后的学习中&#xff0c;如果遇到其他问题&#xff0c;我也会在这里进行更新。各位如有什么补充&#xff0c;欢迎评论区留言~~~问题&#xff1a;IP被封&#xff0…

linux qt检测u盘热插拔,【QT】动态监测U盘插拔

前言在项目中&#xff0c;遇到一个需求&#xff1a;需要动态监测U盘插入&#xff0c;自动读取U盘文件并打开。为了实现这个功能&#xff0c;我们可以使用RegisterDeviceNotification注册设备事件的通知&#xff0c;然后在程序中处理WM_DEVICECHANGE消息来实现步骤RegisterDevic…

童年乐趣

每个人在童年的时候&#xff0c;都无比天真~那时候的我们感情丰富&#xff0c;热血无敌&#xff0c;想跟着四驱兄弟去赛车&#xff1b;想陪着海尔兄弟去冒险&#xff1b;会在孙悟空被误会时流下热泪&#xff1b;也会在哪吒被冤枉时义愤填膺…… 虽然现在看起来有点智障&#xf…

《科学》:中德解析新冠主要蛋白酶晶体结构,有助抑制剂研发

来源&#xff1a;澎湃新闻自新型冠状病毒引起的疫情暴发以来&#xff0c;科学家们一直在努力寻找有效的病毒抑制剂。当地时间3月20日&#xff0c;顶级学术期刊《科学》在线发表了一篇题为“Crystal structure of SARS-CoV-2 main protease provides a basis for design of impr…

render_notebook()结果没有图_来自百度的良心产品!百度iOS截长图App

我们知道百度是国内最大的搜索引擎&#xff0c;但你知道它也会出品一些和搜索无关的精品工具&#xff1f;例如在最近&#xff0c;百度就推出了一款iOS平台上的滚动截长图App&#xff0c;要知道iOS系统一直以来就不支持系统级别的截长图&#xff0c;百度这工具可谓是非常实用了&…

linux emmc vfs错误,Hi3519a EMMC挂载EXT4文件系统失败

环境&#xff1a;hi3519AV100 Hi3519A V100R001C02SPC010问题&#xff1a;使用Hitool5.0.46烧写EMMC&#xff0c;成功烧写uboot、Image和EXT4文件系统&#xff0c;uboot和内核都可以正常启动&#xff0c;报错加载不了文件系统参考文档启动参数设置如下&#xff1a;setenv boota…

2017前端资源汇总

来源于:https://zhuanlan.zhihu.com/p/25229274 Any software that can be written in JavaScript will eventually be written in JavaScript. 下面的项目都列出了github的星数和npmjs上最近一个月的下载数例如 github 106.5k/stars npmjs 93.3k/lm 指有10万6千个github星&…

2020年度国家科学技术奖提名项目公示丨附全名单

来源&#xff1a;科学技术部3月24日&#xff0c;科学技术部发布了《国家科学技术奖励工作办公室公告第95号》文件。该文件称&#xff0c;2020年度国家科学技术奖提名工作已结束&#xff0c;并对2020年度国家自然科学奖、国家技术发明奖通用项目、国家科学技术进步奖通用项目受理…

linux实验试题 cp,cp命令实验,cp命令

cp命令实验&#xff0c;cp命令创建条件[rootlocalhost ~]#mkdir /source[rootlocalhost~]#mkdir /target[rootlocalhost~]#cp /etc/l*.conf /source[rootlocalhost~]#ll /sourcetotal20-rw-r--r--. 1 root root 28 Aug 10 09:24 ld.so.conf-rw-r-----. 1 root root 191 Aug 10 …

codevs 1052:地鼠游戏

http://codevs.cn/problem/1052/ 题目描述 Description 王钢是一名学习成绩优异的学生&#xff0c;在平时的学习中&#xff0c;他总能利用一切时间认真高效地学习&#xff0c;他不但学习刻苦&#xff0c;而且善于经常总结、完善自己的学习方法&#xff0c;所以他总能在每次考试…

机载雷达发展简史:从蝙蝠到机载相控阵

来源&#xff1a;军事高科技在线 从地基起步蝙蝠&#xff0c;虽然像人一样拥有双眼&#xff0c;但它看起东西来&#xff0c;用到的却不是眼睛。蝙蝠从鼻子里发出的超声波在传输过程中遇到物体后会立刻反弹&#xff0c;根据声波发射和回波接收之间的…

苹果手机时区改不了怎么办_天价手机摔了怎么办?苹果:你尽管摔,坏了算我输。...

智能手机比起过去的功能机&#xff0c;好处多到数不过来&#xff0c;但有一点智能手机怎么都比不上功能机&#xff0c;那就是不抗摔。当年的很多功能机那都是可以用来砸核桃的&#xff0c;抗摔性一流&#xff0c;基本不存在摔坏的说法&#xff0c;但智能手机就不一样了&#xf…

linux制作html文档,生成Kernel文档(转换rst为阅读友好的html)

0x00 Kernal与rstLinux kernal的文档使用rst结构化文本编写&#xff0c;阅读kernal\msm-4.1.4\README文档可知&#xff0c;可以通过make htmldocs生成可读的html那就试一试&#xff0c;果然报错了HOSTCC scripts/basic/fixdepDocumentation/Makefile:24: The sphinx-build comm…

简单的python识别的代码_python+opencv实现的简单人脸识别代码示例

#源码如下&#xff1a;#!/usr/bin/env python#codingutf-8import osfrom PIL import Image, ImageDrawimport cvdef detect_object(image):检测图片&#xff0c;获取人脸在图片中的坐标grayscale cv.CreateImage((image.width, image.height), 8, 1)cv.CvtColor(image, graysc…

2020 最新自动驾驶技术报告出炉:Waymo、特斯拉、沃尔沃技术方案大起底

来源&#xff1a;《2020 自动驾驶技术报告》进入 2020 年&#xff0c;自动驾驶技术的跨越式路线与渐进式路线之间的阵营划分已经十分明显。但最终自动驾驶要完全实现无人化&#xff0c;其技术还需要进行不断的迭代和发展。对于自动驾驶的技术进展&#xff0c;WEVOLVER 发布的《…

PC_excel完毕一列英文小写变大写

原创作品&#xff0c;出自 “深蓝的blog” 博客。欢迎转载&#xff0c;转载时请务必注明出处。否则追究版权法律责任。深蓝的blog&#xff1a;http://blog.csdn.net/huangyanlong/article/details/44493869 使用excel中的UPPER函数就可以实现这个目标。介绍例如以下&#xff1a…

c语言if的作用,c语言中if 语句的作用范围示例代码

c语言中if 语句的作用范围示例代码复制代码 代码如下:# include int main(void){if (1 > 2)printf("第一条表达式");printf("第二条表达式");}/*输出结果第二条表达式*/说明if语句的作用范围只有紧跟if的第一条表达式时间&#xff1a; 2013-09-06在高中…