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__()方法,自然不具备单例模式

 

posted on 2018-04-26 21:24  Xiao马  阅读(125)  评论(0编辑  收藏  举报