每周一个设计模式之单例模式
in python with 0 comment

每周一个设计模式之单例模式

in python with 0 comment

天然的的单例模式

其实,Python 的模块就是天然的单例模式。因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。

因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

但如何设计一个单例模式的类,这也就是本文的目的:

自定义单例类

装饰器方法

这个方法使用了装饰器维护了一个字典对象 instances,它的作用是缓存所有单例类,如果不存在则创建,反之直接返回(类似sys.modules)。

In [1]: def singleton(cls):
   ...:     instances = dict()
   ...:     def wrapper(*args, **kwargs):
   ...:         if cls not in instances:
   ...:             instances[cls] = cls(*args, **kwargs)
   ...:         return instances[cls]
   ...:     return wrapper
   ...:
   ...:

In [2]: @singleton
   ...: class Foo(object):
   ...:     pass
   ...:
   ...:

In [3]: foo1 = Foo()

In [4]: foo2 = Foo()

In [5]: id(foo1)
Out[5]: 2396816959528

In [6]: id(foo2)
Out[6]: 2396816959528

基类方法

__new__方法是真正用来实例化对象的方法,所以重写其__new__方法就可以进行单例模式。

而单例模式最为关键的是存在直接返回,不存在则创建。所以将实例对象用一个变量引用住,以后每次创建时直接返回该对象。

In [9]: 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
   ...:

In [10]: class Foo(Singleton):
    ...:     pass
    ...:
    ...:

In [11]: foo1 = Foo()

In [12]: foo2 = Foo()

In [13]: id(foo1)
Out[13]: 2396817286760

In [14]: id(foo2)
Out[14]: 2396817286760

元类方法

"Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don't."

—Tim Peters
Responses