python实现单例模式

171 阅读2分钟

首先,要知道什么是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中有两种或四种方法实现单例模式都可以。

更多技术资讯可关注:itheimaGZ获取(公冢号)