1. __new__魔术方法
# ### __new__ 魔术方法 ''' 触发时机:实例化类生成对象的时候触发(触发时机在__init__之前) 功能:控制对象的创建过程 参数:至少一个cls接受当前的类,其他根据情况决定 返回值:通常返回对象或None ''' class MyClass2(): b = 2 obj2 = MyClass2() # (1) 基本语法 """ 借助object父类中的__new__魔术方法,创建对象 需要传递cls这个参数,代表的是本类,为本类创建对象,进行返回 """ class MyClass(): a = 1 def __new__(cls): print(cls) # <class '__main__.MyClass'> # 借助父类object,里面的__new__魔术方法创建对象 # 1.返回本对象 return object.__new__(cls) # 2.返回其他类的对象 # return obj2 # 3.不返回任何对象 # return None obj = MyClass() print(obj) # 返回本对象 # print(obj.a) # 返回其他类对象 # print(obj.b) # (2) 验证__new__和__init__两个方法的触发时间 """ __new__ 用来创建对象 __init__ 用来初始化对象的 先创建在初始化 __new__ 触发时机快于__init__ """ class MyClass(): def __new__(cls): print(1) return object.__new__(cls) def __init__(self): print(2) obj = MyClass() # 传一个参数的情况 class MyClass(): def __new__(cls,name): return object.__new__(cls) def __init__(self,name): self.name = name obj = MyClass("周永玲") # 传多个参数的情况 class MyClass(): # 多个参数下,用收集参数来保证形参实参一一对应 def __new__(cls,*args,**kwargs): return object.__new__(cls) def __init__(self,name,skin,age): self.name = name self.skin = skin self.age = age obj = MyClass("周玲玲","绿色",108) print(obj.name) # 注意点: """ 如果__new__返回的不是自己本类的对象,不会触发构造方法__init__ """ class MyClass(): def __new__(cls,*args,**kwargs): print("__new__被触发") return obj2 def __init__(self): print("__init__构造方法被触发") obj = MyClass()
# ### 单态模式 : 无论实例化对象多少次,都有且只有一个对象 # (1) 基本语法 """为了节省空间,加快效率,提出单态模式""" class Singleton(): __obj = None def __new__(cls): if cls.__obj is None: cls.__obj = object.__new__(cls) return cls.__obj """ 第一次实例化的时候,cls.__obj is None 返回True 执行object.__new__(cls) 返回对象 让cls.__obj接受对象 return 该对象 第二次实例化的时候,cls.__obj is None 返回False return cls.__obj 内存中堆空间存放的对象返回 第三次实例化的时候,cls.__obj is None 返回False return cls.__obj 内存中堆空间存放的对象返回 以后 .. 每次进行实例化的对象,都是第一次存储的那个对象 就实现了无论实例化几次,都返回同一个对象; """ obj1 = Singleton() obj2 = Singleton() obj3 = Singleton() print(obj1,obj2,obj3) print(obj1 is obj2) # (2) 单态模式 + 构造方法 class Singleton(): __obj = None def __new__(cls,*args,**kwargs): if cls.__obj is None: cls.__obj = object.__new__(cls) return cls.__obj def __init__(self,name): self.name = name obj1 = Singleton("李诗韵") obj2 = Singleton("黄乐锡") print(obj1.name) print(obj2.name) """ 第一次实例化的时候, self.name = 李诗韵 第一次实例化的时候, 返回的是第一次实例化出来的对象 将该对象以前的name属性 从李诗韵改成黄乐西 self.name = 黄乐西 打印 obj1.name obj2.name 都是黄乐西 """
2.
day19