__new__()方法及单例模式

本文深入探讨了Python中类的__new__方法的作用,特别是在实例化过程中如何传递参数,并通过示例解释了单例模式的实现方式。文章详细介绍了如何使用*args和**kwargs在__new__方法中接收初始化参数,以及如何利用这些参数进行对象的正确创建。同时,通过对比不同实例创建方法,展示了字典拆包和参数传递的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、new方法
总结,__init__方法中初始化的参数实际上是__new__方法传进去的,所以new方法中必须要接收初始化的参数,用*args,**kwargs来实现

In [166]: class D():
     ...:     def __new__(cls,*args,**kwargs):  # 创建对象时参数先传给new,
     new指向成功后将参数传给init方法,所以此处如果不写*args,**kwargs
     则下面用D(10,20,30,o=100,p=50)创建实例对象时会报new方法只要一个参数
     but 6 given!
     ...:         return object.__new__(D)
     ...:     
     ...:     def __init__(self,x,y,z,o=0,p=9):
     ...:         self.x = x
     ...:         self.y = y
     ...:         self.z = z
     ...:         self.o = o
     ...:         self.p = p
     ...:     def dd(self):
     ...:         print("D dd method is running")
     ...:         

In [167]: dit = {"o":100,"p":50}
In [168]: d = D(10,20,30,dit) # 相当于10 20 30 dit四个参数传到*args元组里面去了
In [169]: d.p # 所以p用的是默认值,init前面四个参数用的是元组拆包传值
Out[169]: 9
In [170]: d.o # 所以o传的是个字典dit
Out[170]: {'o': 100, 'p': 50}
In [171]: d = D(10,20,30,*dit)  # *表示拆包,1颗*拆的是键
In [172]: d.p
Out[172]: 'p'
In [173]: d.o
Out[173]: 'o'

In [174]: d = D(10,20,30,**dit)  # 两颗*表示拆键值对,
即把dit字典拆成o=100,p=50
In [175]: d.p
Out[175]: 50
In [176]: d.o
Out[176]: 100

In [177]: d1 = D(10,20,30,**dit)
In [178]: d2 = D(10,20,30,**dit)

In [179]: id(d1)
Out[179]: 140290162490952
In [180]: id(d2)
Out[180]: 140290162542016

二、单例模式

 class D():
     ...:     __instance = None  # 不对外访问,_ _私有化
     ...:     __is_init = False
     ...:     def __new__(cls,*args,**kwargs):  # 要加*args,**kwargs传参
     ...:         if cls.__instance is None:  # 类属性要加cls.访问
     ...:             cls.__instance = object.__new__(D) # 实际创建对象时new只需要一个参数,这里要注意下
     ...:         return cls.__instance

     ...:     def __init__(self,x,y,z,o=0,p=9):
     ...:         if not self.__is_init:  # 类属性用类名.或者self.访问,这里找不到cls变量不能用cls.访问
     ...:             self.x = x
     ...:             self.y = y
     ...:             self.z = z
     ...:             self.o = o
     ...:             self.p = p
     ...:             self.__is_init = True
     ...:             
     ...:     def dd(self):
     ...:         print("D dd method is running")

执行结果:

In [186]: d4 = D(10,20,30,o=90,p=80)
In [187]: d5 = D(40,50,60,o=100,p=800)

In [192]: d4.x
Out[192]: 10
In [193]: d4.o
Out[193]: 90
In [194]: d5.o
Out[194]: 90
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值