最近在学到Python中的__new__方法时被弄懵逼了,一开始实在是很难理解,有很多地方想不通(本人强迫症)。最近自己慢慢思索得出了能说服自己的理解:

说__new__方法之前要先提到__init__方法,__init__方法是普遍认为的Python类的构造方法,在我们对类进行实例化的时候,Python解释器会调用__init__方法对我们在init方法中定义的属性进行初始化,比如:

classdemo():def __init__(self,arg,kwarg): #定义属性并初始化

self.arg=arg

self.kwarg=kwargdefOutput(self):print(self.arg)print(self.kwarg)

a= demo("NMSL","WSND") #实例化

a.Output() #调用类中的Output方法

但是其实在Python中,__init__并不是真正的构造函数,准确的说,__new__加__init__才是真正的构造函数,下面详细说一下__new__方法。

当我们在对类进行实例化的时候,Python解释器会从__new__方法的返回值中获取到实例对象的信息,在上面代码的例子中,我们把类demo进行实例化,对象为a

在这个过程中,类demo是怎么确定它的实例对象是a呢,就是__new__方法返回了这个值,这个值就是a,然后Python解释器就知道了demo这个类的对象为a,其实这里的返回值最后被Python解释器告诉__init__方法,init方法中的关键字self其实就是这个a,因为self代表的是类的对象。

__new__方法还有另一个用处就是用来实现单例设计模式以及继承不可变类的时候方便我们定制类:

classnewfloat(float):def __new__(cls,value):return super().__new__(cls,round(value,4))

i= newfloat(3.14529)print(i)

这里的思路是用来接收__new__方法的返回值再打印出来。

老实说我在很多文章下面看到过关于__new__方法的应用,都是拿这个举例子,但是我觉得根本没有必要这样,我觉得可以这样:

classdemo(int):def __init__(self,arg):

self.arg=arg

self.arg= round(self.arg,4)print(self.arg)

a= demo(3.1415926)

这样的写法同样能实现功能。

单例设计模式是为了解决一个类有多个对象的时候,多个对象引用同一个内存地址,以减少内存占用的问题。

实现思路:

重写父类的__new__方法,使每次返回的内存地址引用都为同一个。

classdemo(object):

ins=Nonedef __new__(cls):if cls.ins ==None:

cls.ins= super().__new__(cls)return cls.ins

a = demo()

b = demo()

print(a)

print(b)

这里的思路是:定义一个类属性ins为空值,再在重写__new__方法时候用if语句进行判断,如果ins为空则赋给它__new__方法的返回值,当用a去实例化demo时,

实际上是Python解释器为这次实例化开辟了一片内存空间,a就是引用了这个内存地址。

然后我们再用b去实例化demo,由于ins的值已经被改写,所以返回的是同样的之前a对象的内存地址,这样就成功实现了单例设计模式。

这里必须好好解释一下__new__方法的参数,在定义new方法时,在参数栏里不能写self,而是写cls,self代表的是类的实例,而cls则代表的是类本身。

继承不可变类型,我们知道Python中的不可变类型有int,str和tuple,但是Python中有这么一个思想:万物皆对象。也就是说,int,str和tuple这中数据类型其实也是一种对象,拿字符串举例,我们可以利用count之类的方法直接对字符串进行操作,但是这其实是Python内置类str中定义的方法,我们可以用dir()方法查看类中定义有哪些方法,但是在重写new方法时最多只能多传一个参数,这是为什么?

下面时我自己的解释,我们平时用内置方法比如count()时,一次只能对一个字符串进行操作,理所应当,每次当我们重写str类中定义的方法时,只能传入一个值。

其他注意事项:

__init__方法不能有返回值,而__new__方法却必须有返回值。

如有错误,请指正,感激不尽。

python 多继承 __new___Python3中的__new__方法以及继承不可变类型类的问题相关推荐

  1. python函数实例化_Python中的__new__()方法与实例化

    __new__()是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在Python 中 存在于类里面的构造方法__init__()负责将类的实例化,而在__init__()启动之前 ...

  2. Python中的__new__()方法的使用

    __new__() 函数只能用于从object继承的新式类. 先看下object类中对__new__()方法的定义: class object:   @staticmethod # known cas ...

  3. python new方法_Python中的__new__()方法的使用

    __new__() 函数只能用于从object继承的新式类. 先看下object类中对__new__()方法的定义: class object: @staticmethod # known case ...

  4. JS中通过call方法实现继承

    JS中通过call方法实现继承 原文:JS中通过call方法实现继承 讲解都写在注释里面了,有不对的地方请拍砖,谢谢! <html xmlns="http://www.w3.org/1 ...

  5. python怎么创建方法_python中的__new__方法

    print(obj) #打印结果:<__main__.Foo object at 0x000002636FEAA208> 事实上如果(新式)类中没有重写__new__()方法,即在定义新式 ...

  6. python中文读音ndarray-numpy中的ndarray方法和属性详解

    NumPy数组的维数称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推.在NumPy中,每一个线性的数组称为是一个轴(axes),秩其实是描述轴的数量.比如说,二维数组相当于是一个一维数 ...

  7. python怎么new对象_Python使用__new__()方法为对象分配内存及返回对象的引用示例

    本文实例讲述了Python使用__new__()方法为对象分配内存及返回对象的引用.分享给大家供大家参考,具体如下: demo.py(__new__方法): class MusicPlayer(obj ...

  8. python ctime函数_Python中的ctime()方法使用教程

    ctime()方法转换,因为历元到表示本地时间的字符串表示以秒为单位的时间.如果不设置秒时或None,所返回的时间的当前time()被使用.使用asctime(localtime(secs)).不使用 ...

  9. python-面向对向-静态方法的继承-父类中的super方法

    一,普通继承 重写静态方法 更正,第十行是类方法 扩展父类的静态方法 换一种调用形态 多继承的情况 新增一个Mother类 执行顺序 使用基类的方法时,关注顺序 换个顺序 小结继承的规则 子类继承了类 ...

最新文章

  1. Unreal Engine 4 RenderTarget制作Live Camera效果
  2. Scrapy框架基础使用
  3. c1xx: fatal error C1356: 无法找到 mspdbcore.dll
  4. python下载m3u8地址_python 下载m3u8视频的示例代码
  5. java代码没错却运行不了_Java代码没错误,tomcat能正常运行,但是我的项目主页却一直显示不了,显示404错误...
  6. Coding中遇到的BUG集合~
  7. 巧用Graphviz和pvtrace等工具可视化C函数调用
  8. 全球及中国食品供应区块链行业运行形势及未来投资规模建议报告2021年版
  9. POJ - 2773 Happy 2006(欧几里得+构造)
  10. java构建protobuf中的map,Protobuf对象作为Maps中的键
  11. Ubuntu主题更换
  12. 如何在支付宝成为增加个人服务器,支付宝支付,服务器如何生成支付订单
  13. Axure高保真移动端电商app通用模板、axure高保真移动端教育app通用模板、旅游app通用模板、电商app、教育app、旅游app 、直播、在线教育、旅游、Axure原型、rp原型
  14. 翻译:TRUNCATE TABLE(已提交到MariaDB官方手册)
  15. SQL Server 日期格式
  16. 【转载】PHP.INI配置:Session配置详细说明教程
  17. listview数据下载后不更新
  18. 2023考研高数接力题典1800习题讲解
  19. java获取本机ip地址和tomcat端口号
  20. 你听过“费斯汀格法则”吗?多少人因为不懂而被残害!好文!

热门文章

  1. 记一种数据库水平扩展的技巧
  2. 连接池,数据库连接池
  3. /etc/sysconfig/network-script/ifcfg-eth0究竟怎么填!!!
  4. 大剑无锋之如何评判一个算法的优劣【面试推荐】
  5. 【案例分析】分布式系统的接口幂等性设计!
  6. Purpose of cmove instruction in x86 assembly? | cmove 指令如何避免错误的分支预测带来的开销?
  7. 【JavaScript】前端模块化:import 和 export 的使用
  8. 【Java入门】桌球小游戏
  9. C语言 realloc函数 带着内存游走的函数
  10. 看动画学算法之:递归和递归树