方式一:使用模块
模块是天然的单例
# 如果已经导入的模块被重新导入,Python不会重新解释一遍
# 而是从内存中直接将原来导入的值拿来使用
使用这种机制,可以维护一个模块间的公共对象,所有模块都可以往这个对象里传值,再取出
==========
# 作为Python模块时是天然的单例模式 #创建一个sington.py文件,内容如下: class Singleton(object): def foo(self): pass mysington = Singleton() # 运用 from sington import mysington # 不论import多少次,mysington对象都是单例的 mysington.foo()
==========
''' 把全局状态放在私有变量中 并提供用于访问此变量的公开函数 ''' def get(refresh=False): if refresh: get.rates = {} if get.rates: return get.rates get.rates['usd'] = 0.4 # 初始化,可以从URL更新 return get.rates get.rates = {} ''' 以上语句放入:Rates.py模块中 创建了字典rates并将其作为Rates.get函数的属性。 第一次执行: import Rates Rates.get()或者Rates.get(refresh=True) 时,会下载全新的汇率数据,其他时候只需把最近下载的那份数据返回就行了。 此处没有引入类,依然把汇率数据做成了单例的。 '''
方式二:重写__new__方法
class Singleton: def __new__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instance class Foo(Singleton): # 继承Singleton的类都是单例的,线程安全 pass f1 = Foo() f2 = Foo() f3 = Foo() print(id(f1), id(f2), id(f3)) # 34879944 34879944 34879944