python 面向对象-类的魔法方法__new__()和单例模式(九)

本文详细解析了Python中__new__方法的作用,它是如何在新式类中控制对象创建的。通过实例展示了__new__方法的覆盖及其影响,包括单例模式的应用。同时,解释了__new__与__init__的区别,并通过内存地址展示了单例模式确保类只创建一个对象的原理。

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

object类中__new__方法:

说明: __new__()创建和返回一个新的对象。通俗说:该魔法属性是用来创建实例对象的。接下来我们看一下它的是如何创建对象的。 

1、__new__()是在新式类中新出现的方法,它作用在构造方法建造实例之前。

2、__new__() 方法始终都是类的静态方法,即使没有被加上静态方法装饰器。

__new__()方法用于定义创建对象时执行的操作 > 对象的创建由new方法控制
init  >  只是对象创建的时候会自动执行的方法

new > 对象 > init
object类中的__new__()方法完成对象创建过程中的内存空间申请, 对象属性初始化等一系列的操作。
    1.__new__()方法创建对象时自动运行。
    2.覆盖object类中的__new__方法后创建对象将执行覆盖后的方法
之前去创建对象,从来没有自己去调用过new方法....
实际上就是默认调用了object的 new方法......

(1) 对象的创建 > object里面的new方法的执行....

# 父类:方法和属性
class Person:
    #成员变量
    def __init__(self):
         self.name=None
         self.sex=None

    #成员方法
    def show(self):
        print(f'{self.name},{self.sex}')


# 对象创建,所以init成功被执行,自动调用了object的new方法,导致对象成功的创建
# pe=Person()
# pe.show()

(2) 重写了new方法, 那么将不再去执行 object里面的new方法....对象是否还能够成功的创建

class Person:

    def __new__(cls, *args, **kwargs):
        print('重写创建对象!!')
        pass

    #成员变量
    def __init__(self):
         self.name=None
         self.sex=None

    #成员方法
    def show(self):
        print(f'{self.name},{self.sex}')

#发生异常:AttributeError: 'NoneType' object has no attribute 'show'
#原因: 对象的创建,必须由object的new方法 去创建
# pe=Person()
# pe.show()

  

(3)new方法,影响对象的创建,一个类创建无数个对象, 划分出无数个单独的内存空间

       解决: 控制new方法, 让一个类只创建出一个对象,使用单例模式, 单个实例对象模式!!

class Person:
    # 重写object用来创建对象的new方法
    def __new__(cls, *args, **kwargs):
        print('重写new方法!!')
        # 调用object的new方法,让对象成功的创建
        #创建对象,一般默认名称instance
        instance =object.__new__(Person)
        return instance   #返回创建对象

    #成员变量
    def __init__(self):
         self.name=None
         self.sex=None

    #成员方法
    def show(self):
        print(f'{self.name},{self.sex}')

#init方法被成功的执行 > 对象成功的创建 > 依赖的是object.__new__(Person)
pe=Person()
pe.show()

 

(4) 单例模式: 单个实例对象模式 > 一个类控制只能创建一个对象

class Person:
    #成员变量
    def __init__(self):
         self.name=None
         self.sex=None

p1=Person()
p2=Person()
# 每一个对象就是一片单独的内存空间
print(id(p1))  #2611294271808
print(id(p2))  #2611294540416

说明:

控制一个类只能创建出一个对象
解决:重写了new方法之后,object.__new__(Person)执行一遍,就是一个对象的创建
    如果我们控制这句创建对象的代码object.__new__(Person) 只能执行一遍

加入是第一次创建对象,那么此时此刻类变量的值是__instance = None
if cls.__instance == None 
   __instance = object.__new__(Person)  #对象成功的创建
return __instance 

第二次创建对象,__instance的值已经不是None了, 是一个对象, 是第一个对象
if cls.__instance == None  #条件不成立 
 object.__new__(Person)  #创建对象不再被执行
return __instance  #依旧是第一个对象

第三次创建对象,__instance的值已经不是None了, 是一个对象, 是第一个对象
if cls.__instance == None  #条件不成立 
 object.__new__(Person)  #创建对象不再被执行
return __instance #依旧是第一个对象
class Person:
    # 类变量 (私有的)
    __instance=None
    # 重写object用来创建对象的new方法
    def __new__(cls, *args, **kwargs):
        print('重写new方法!!')
        # 调用object的new方法,让对象成功的创建
        if cls.__instance==None:
            #创建对象,一般默认名称instance
            cls.__instance =object.__new__(Person)
        return cls.__instance   #返回创建对象

    #成员变量
    def __init__(self):
         self.name=None
         self.sex=None

    #成员方法
    def show(self):
        print(f'{self.name},{self.sex}')

#init方法被成功的执行 > 对象成功的创建 > 依赖的是object.__new__(Person)
pe1=Person()
pe2=Person()
print(id(pe1))   #1938233784928
print(id(pe2))   #1938233784928

说明:通过id内存地址的打印发现他们是同一个对象

is  和 == 的区别
==  > 判断的是两边的数据是否相等
is  > 判断的是两边的内存地址是否相等


list1=[1,2,3]
list2=[1,2,3]
#地址不同
print(id(list1))
print(id(list2))
#比较的值
print(list1 == list2)
#比较的内存地址
print(list1 is list2)
# list1列表, 不是真正的保存了 1 2 3 真实的数据,而是保存了他们的引用..
print(id(list1[0])) #140706885998240
print(id(list1[1])) #140706885998272

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值