单例模式是一种对象创建型模式,确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类。
代码:
# 实例化一个单例
class Singleton(object):
__instance = None
def __new__(cls, age, name):
# 如果类属性__instance的值为None,
# 那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时
# 能够知道之前已经创建过对象了,这样就保证了只有1个对象
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
a = Singleton(20, "xiaoming")
b = Singleton(22, "xiaozhang")
print(id(a))
print(id(b))
a.age = 21
print(b.age)
the result is : 36707856
36707856
21
# 支持多线程的单例模式 ( 这种方式实现的单例模式,使用时会有限制,以后实例化必须通过 obj = Singleton.instance() 如果用 obj=Singleton() ,这种方式得到的不是单例 )
import time
import threading
class Singleton(object):
_instance_lock = threading.Lock()
def __init__(self):
time.sleep(1)
@classmethod
def instance(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"):
with Singleton._instance_lock:
if not hasattr(Singleton, "_instance"):
Singleton._instance = Singleton(*args, **kwargs)
return Singleton._instance
def task(arg):
obj = Singleton.instance()
print(obj)
for i in range(10):
t = threading.Thread(target=task,args=[i,])
t.start()
time.sleep(2)
obj = Singleton.instance()
print(obj)
<__main__.Singleton object at 0x00000000032FA080><__main__.Singleton object at 0x00000000032FA080>
<__main__.Singleton object at 0x00000000032FA080><__main__.Singleton object at 0x00000000032FA080>
<__main__.Singleton object at 0x00000000032FA080><__main__.Singleton object at 0x00000000032FA080><__main__.Singleton object at 0x00000000032FA080><__main__.Singleton object at 0x00000000032FA080>
<__main__.Singleton object at 0x00000000032FA080><__main__.Singleton object at 0x00000000032FA080>
<__main__.Singleton object at 0x00000000032FA080>
class Person(object):
instance = None # 引用唯一的对象
is_first_run = True # 如果为True代表第一次创建对象
def __new__(cls, *args, **kwargs):
if cls.instance == None # 只有当instance为None时才创建新对象
cls.instance = object.__new__(cls)
return cls.instance
def __init__(self, name = ‘’): # 只有当第一次创建对象才应该初始化数据
if Person.is_first_run:
self.name = name
Person.is_first_run = False
def set_name(self, new_name): # 单例模式一般用set方法修改属性
self.name = new_name
zs = Person('zhangsan')
print('zs=', zs.name)
ls = Person() # 对于不想传参的情况,可以使用缺省参数
ls.set_name('lisi')
print('ls=', ls.name)