问题:如何实现单例模式?
class Singleton (object) :
def __new__ (cls, *args, **kwargs) :
if not hasattr(cls, '_instance' ):
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
class Singleton (object) :
_instance = None
def __new__ (cls, *args, **kwargs) :
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
from functools import wraps
def singleton (cls) :
instances = {}
@wraps(cls)
def wrapper (*args, **kwargs) :
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
通过元类来创建单例模式,因为元类是用于创建类对象的类,类对象创建实例对象时一定会调用call 方法,因此在调用call 时候保证始终只创建一个实例即可。
class Singleton (type) :
def __call__ (cls, *args, **kwargs) :
if not hasattr(cls, '_instance' ):
cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instance
class Foo (object) :
__metaclass__ = Singleton
通过共享属性来实现单例模式(通过这种方式实现,只是两个对象有相同的属性,但是在实例化之后,one is two 将会返回False), 将所有实例的dict 指向同一个字典,这样实例就共享相同的方法和属性。对任何实例的名字属性的设置,无论是在init 中修改还是直接修改,所有的实例都会受到影响。不过实例的id是不同的。要保证类实例能共享属性,但不和子类共享。
class Singleton (object) :
_state = {}
def __new__ (cls, *args, **kwargs) :
orig = super(Singleton, cls).__new__(cls, *args, **kwargs)
orig.__dict__ = cls._state
return orig
使用模块, Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
class Singleton (object) :
def foo (self) :
pass
my_singleton = Singleton()
import sys
class Singleton (object) :
pass
sys.modules[__name__] = Singleton()