标签:赋值 people def 提醒 创建 默认 __new__ 导致 first
class People(object): """单类模式""" __instance = None# 创建变量引用创建的实例对象 def __new__(cls, *args, **kwargs): if cls.__instance == None: cls.__instance = object.__new__(cls)# 创建对象并赋值给这个对象的引用 return cls.__instance def __init__(self, name): # 每次创建对象都会执行_init_方法 导致后面对象的name会覆盖前面对象的name属性 # 所有对象的name属性 都和最后那个定义的对象相同 因为被覆盖了 self.name = name p1 = People(‘ll‘) p2 = People(‘kk‘) print(p1) # <__main__.People object at 0x7fcdda812860> print(p2) # <__main__.People object at 0x7fcdda812860> 表明 p1 p2是同一个对象 print(p1.name) # kk print(p2.name) # kk 因为实例对象只创建了一个,init方法却运行了两次,name属性与最后一次创建的一致
下面我们再写一个正规的, 能达到只能建立一个实例对象,并且在建立实例对象时传入的参数不能改变实例属性值的代码(即__init__方法只能被调用一次),要想改变实例属性的值只能在外部重新赋值p1.name = 张三 或 在类内部写入函数实现 def set_name(self, name): self.name = name.
上句话总结起来就是:正规单例模式,__new__,__init__方法各自只能执行一次 Demo:
class People(object): __instance = None # 创建变量 表示是否创建过对象 __first_run = True # 如果为True 表示第一次运行 def __new__(cls, *args, **kwargs): if cls.__instance == None: cls.__instance = object.__new__(cls) return cls.__instance def __init__(self, name): # 确保init方法只被执行一次 if People.__first_run: # 所有实例对象的name属性都与第一个的相同 self.name = name People.__first_run = False p1 = People(‘ll‘) p2 = People(‘kk‘) print(p1) # <__main__.People object at 0x7fb7c5f49828> print(p2) # <__main__.People object at 0x7fb7c5f49828> print(p1.name) # ll print(p2.name) # ll
定义类时有2种形式:新式类和经典类
Python 2.x中默认都是经典类,只有显式继承了object才是新式类
Python 3.x中默认都是新式类,不必显式的继承object
另外提醒 只有新式类才有__new__()方法 才可以采用单例模式 经典类不具备__new__()方法,自然不具备单例模式
标签:赋值 people def 提醒 创建 默认 __new__ 导致 first
原文地址:https://www.cnblogs.com/m-j-y/p/8955100.html