1. 程式人生 > >python中7種實現單例模式的方法:staticmethod、classmethod、類屬性方法、__new__、裝飾器、元類、名字覆蓋

python中7種實現單例模式的方法:staticmethod、classmethod、類屬性方法、__new__、裝飾器、元類、名字覆蓋

本文的以下實現方法為了簡單起見不考慮執行緒安全。

一:staticmethod

程式碼如下:
class Singleton(object):
    instance = None
    def __init__(self):
        raise SyntaxError('can not instance, please use get_instance')

    @staticmethod
def get_instance():
        if Singleton.instance is None:
            Singleton.instance = object
.__new__(Singleton) return Singleton.instance a = Singleton.get_instance() b = Singleton.get_instance() print('a id=', id(a)) print('b id=', id(b))
該方法的要點是在__init__丟擲異常,禁止通過類來例項化,只能通過靜態get_instance函式來獲取例項;因為不能通過類來例項化,所以靜態get_instance函式中可以通過父類object.__new__來例項化。

二:classmethod

和方法一類似,程式碼:
class 
Singleton(object): instance = None def __init__(self): raise SyntaxError('can not instance, please use get_instance') @classmethod def get_instance(cls): if Singleton.instance is None: Singleton.instance = object.__new__(Singleton) return Singleton.instance a = Singleton.get_instance() b = Singleton.get_instance() print
('a id=', id(a)) print('b id=', id(b))
該方法的要點是在__init__丟擲異常,禁止通過類來例項化,只能通過靜態get_instance函式來獲取例項;因為不能通過類來例項化,所以靜態get_instance函式中可以通過父類object.__new__來例項化。

三:類屬性方法

和方法一類似, 程式碼:
class Singleton(object):
    instance = None
    def __init__(self):
        raise SyntaxError('can not instance, please use get_instance')

    def get_instance():
        if Singleton.instance is None:
            Singleton.instance = object.__new__(Singleton)
        return Singleton.instance

a = Singleton.get_instance()
b = Singleton.get_instance()
print(id(a))
print(id(b))
該方法的要點是在__init__丟擲異常,禁止通過類來例項化,只能通過靜態get_instance函式來獲取例項;因為不能通過類來例項化,所以靜態get_instance函式中可以通過父類object.__new__來例項化。

四:__new__

常見的方法, 程式碼如下:

class Singleton(object):
    instance = None
    def __new__(cls, *args, **kw):
        if not cls.instance:
            # cls.instance = object.__new__(cls, *args)
cls.instance = super(Singleton, cls).__new__(cls, *args, **kw)
        return cls.instance


a = Singleton()
b = Singleton()
print(id(a))
print(id(b))

五:裝飾器

程式碼如下:

def Singleton(cls):
    instances = {}

    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance


@Singleton
class MyClass:
    pass
a = MyClass()
b = MyClass()
c = MyClass()

print(id(a))
print(id(b))
print(id(c))

六:元類

python2版:
class Singleton(type):
    def __init__(cls, name, bases, dct):
        super(Singleton, cls).__init__(name, bases, dct)
        cls.instance = None
def __call__(cls, *args):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args)
        return cls.instance


class MyClass(object):
    __metaclass__ = Singleton


a = MyClass()
b = MyClass()
c = MyClass()
print(id(a))
print(id(b))
print(id(c))
print(a is b)
print(a is c)

或者:
class Singleton(type):
    def __new__(cls, name, bases, attrs):
        attrs["_instance"] = None
        return super(Singleton, cls).__new__(cls, name, bases, attrs)

    def __call__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instance


class Foo(object):
    __metaclass__ = Singleton

x = Foo()
y = Foo()
print(id(x))
print(id(y))

python3版:
class Singleton(type):
    def __new__(cls, name, bases, attrs):
        attrs['instance'] = None
        return super(Singleton, cls).__new__(cls, name, bases, attrs)

    def __call__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
        return cls.instance


class Foo(metaclass=Singleton):
    pass
x = Foo()
y = Foo()
print(id(x))
print(id(y))

七:名字覆蓋

程式碼如下:
class Singleton(object):
    def foo(self):
        print('foo')

    def __call__(self):
        return self
Singleton = Singleton()

Singleton.foo()

a = Singleton()
b = Singleton()
print(id(a))
print(id(b))