单例模式
单例模式提供了这样一个机制,即确保类有且只有一个特定类型的对象,并提供全局访问点。
单例模式通常用于下列情形,例如日志记录或数据库操作、打印机后台处理程序,以及其它程序--该程序运行过程中只能生成一个实例,以避免对同一资源产生冲突请求。
简言之,单例模式的意图如下:
- 确保类只有一个对象被创建
- 为对象提供一个访问点,以使程序可以全局访问该对象
- 控制共享资源的并行访问
实现单例模式的一个简单方法是,是构造函数私有化,并创建一个静态方法来完成对象的初始化。
class Singleton(object):
def __new__(cls):
if not hasattr(cls,'instance'):
cls.instance = super(Singleton,cls).__new__(cls)
return cls.instance
s = Singleton()
print("object created",s)
s1 = Singleton()
print("object created",s1)
help(Singleton.__new__)
# help(type)
object created <__main__.Singleton object at 0x000001C75E466160>
object created <__main__.Singleton object at 0x000001C75E466160>
Help on function __new__ in module __main__:
__new__(cls)
Create and return a new object. See help(type) for accurate signature.
单例模式中的懒汉式实例化
懒汉式实例化确保在实际需要时才创建对象
class Singleton(object):
__instance = None
def __init__(self):
if not Singleton.__instance:
print("__init__method called...")
else:
print("Instance already created:",self.getInstance())
@classmethod
def getInstance(cls):
if not cls.__instance:
cls.__instance = Singleton()
return cls.__instance
s = Singleton()
print("object created",Singleton.getInstance())
s1 = Singleton()
help(Singleton.getInstance)
help(Singleton.__init__)
__init__method called...
__init__method called...
object created <__main__.Singleton object at 0x000001C75E45AF28>
Instance already created: <__main__.Singleton object at 0x000001C75E45AF28>
Help on method getInstance in module __main__:
getInstance() method of builtins.type instance
Help on function __init__ in module __main__:
__init__(self)
Initialize self. See help(type(self)) for accurate signature.
单例与元类
元类是一个类的类,即一个类是他的元类的一个类。我们可以通过元类从预定义的pyhon类中创建自己类型的类。
在python中一切皆对象,类的定义由他的元类决定,所以当我们用类A创建一个类时,python通过A=type(name,bases,dict)创建他。
- name:类的名称
- bases:基类
- dict:属性变量
现在,如果一个类有预定义的元类(名为Metals),那么python可以通过A=MetaKls(name,bases,dict)来创建类
class MyInt(type):
def __call__(cls,*args,**kwds):
print("***** Here's My Int *****",args)
print("Now do whatever you want with these objects...")
return type.__call__(cls,*args,**kwds)
class int(metaclass=MyInt):
def __init__(self,x,y):
self.x = x
self.y = y
i = int(4,5)
help(MyInt.__call__)
***** Here's My Int ***** (4, 5)
Now do whatever you want with these objects...
Help on function __call__ in module __main__:
__call__(cls, *args, **kwds)
Call self as a function.
上述代码表示当使用int(4,5)实例化int类时,MyInt元类的call方法被调用,这意味着现在元类控制着对象的实例化。
这样的思路同样适合单例模式,可以使用元类创建单例。
class MetaSingleton(type):
__instances = {}
def __call__(cls,*args,**kwargs):
if cls not in cls.__instances:
cls.__instances[cls] = super(MetaSingleton,\
cls).__call__(*args,**kwargs)
return cls.__instances[cls]
class Logger(metaclass=MetaSingleton):
pass
logger1 = Logger()
logger2 = Logger()
print(logger1,logger2)
<__main__.Logger object at 0x000001EC13B83DA0> <__main__.Logger object at 0x000001EC13B83DA0>
单例模式的缺点
- 全局变量可能在某处已被修改,但开发人员仍认为其没有发生变化,从而该变量在其他应用程序中依然被调用
- 可能对同一对象创建多个引用
- 所有依赖于全局变量的类都会由于一个类发生变化而紧密耦合为全局数据,从而可能在无意间影响另一个类
网友评论