首先,要知道什么是python的单例模式,所谓单例模式就是一个类只能创建一个实例化。 然后,就是python单例模式的方法,总共可以分为两大种,四小种,一会就会说的。 首先,方法一: - class Singleton(type):
- def __init__(cls, name, bases, dict):
- super(Singleton, cls).__init__(name, bases, dict)
- cls.instance = None
-
- def __call__(cls, *args, **kw):
- if cls.instance is None:
- cls.instance = super(Singleton, cls).__call__(*args, **kw)
- return cls.instance
-
- class MyClass(object):
- __metaclass__ = Singleton
-
- print MyClass()
- print MyClass()
方法二:使用装饰器(decorator)
- def singleton(cls, *args, **kw):
- instances = {}
- def _singleton():
- if cls not in instances:
- instances[cls] = cls(*args, **kw)
- return instances[cls]
- return _singleton
-
- @singleton
- class MyClass(object):
- a = 1
- def __init__(self, x=0):
- self.x = x
-
- one = MyClass()
- two = MyClass()
-
- two.a = 3
- print one.a
- #3
- print id(one)
- #29660784
- print id(two)
- #29660784
- print one == two
- #True
- print one is two
- #True
- one.x = 1
- print one.x
- #1
- print two.x
方法三:使用__metaclass__元类来实现
- class Singleton2(type):
- def __init__(cls, name, bases, dict):
- super(Singleton2, cls).__init__(name, bases, dict)
- cls._instance = None
- def __call__(cls, *args, **kw):
- if cls._instance is None:
- cls._instance = super(Singleton2, cls).__call__(*args, **kw)
- return cls._instance
-
- class MyClass(object):
- __metaclass__ = Singleton2
-
- one = MyClass()
- two = MyClass()
-
- two.a = 3
- print one.a
- #3
- print id(one)
- #31495472
- print id(two)
- #31495472
- print one == two
- #True
- print one is two
- #True
方法四:通过共享属性来实现,所谓共享属性,最简单直观的方法就是通过__dict__属性指向同一个字典dict
- class Borg(object):
- _state = {}
- def __new__(cls, *args, **kw):
- ob = super(Borg, cls).__new__(cls, *args, **kw)
- ob.__dict__ = cls._state
- return ob
-
- class MyClass(Borg):
- a = 1
-
- one = MyClass()
- two = MyClass()
-
- #one和two是两个不同的对象,id, ==, is对比结果可看出
- two.a = 3
- print one.a
- #3
- print id(one)
- #28873680
- print id(two)
- #28873712
- print one == two
- #False
- print one is two
- #False
- #但是one和two具有相同的(同一个__dict__属性),见:
- print id(one.__dict__)
- #30104000
- print id(two.__dict__)
其实吧,从本质上来讲,方法一二三都属于一种单例化模式的方法,与第四种不同,所以认为python中有两种或四种方法实现单例模式都可以。
|