Date
Nov. 21st, 2024
 
2024年 10月 21日

Post: Python : 单例模式的实现

Python : 单例模式的实现

Published 12:03 Mar 31, 2015.

Created by @ezra. Categorized in #Programming, and tagged as #Python.

Source format: Markdown

Table of Content

单利模式(Singleton)是大部分开发任务中常用的设计模式之一。这里我主要总结一下 Python 中的单利实现方式。

我综合了许多人的意见,主要有这样几种实现方式:

  • 类实例与类变量绑定。

  • 共享属性。

  • 使用装饰器。

  • 使用元类。

类实例与类变量绑定

先来看第一种方式:

class Singleton(object):
    _instance = None

    def __new__(cls, *args):
        if not isinstance(cls._instance, cls):
            cls._instance = super(Singleton, cls).__new__(cls, *args)
        return cls._instance

看起来似乎不错,但却存在一个严重的问题 —— 如果某个类继承了这个 Singleton 类,它将可以重写了父类的 __new__ 方法,这样就会导致其失去唯一性。

class MyClass(Singleton):
    def __new__(cls, *args):
        return super(D, cls).__new__(cls, *args)

共享属性

class Borg(object):  
    _state = {}  
    def __new__(cls, *args, **kw):  
        ob = super(Borg, cls).__new__(cls, *args, **kw)  
        ob.__dict__ = cls._state  
        return ob

使同一个类的所有实例具有相同的属性来实现单例效果。但这样做,生成的实例将是不同的对象。

使用装饰器

通过装饰器实现的方式,其实可以看做第一种方式的升级本版本。

def singleton(_cls):
    insts = {}

    def getinstance(*args, **kwargs):
        if _cls not in insts:
            insts[_cls] = _cls(*args, **kwargs)
        return insts[_cls]
    return getinstance

@singleton
class MyClass(object):
    pass

问题显而易见,而我们也并不希望在此之外定义太多的内容。

使用元类

事实上,通过使用元类(__metaclass__)也可以达到单例效果,并且不失为一种好方法。

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 
Pinned Message
HOTODOGO
The Founder and CEO of Infeca Technology.
Developer, Designer, Blogger.
Big fan of Apple, Love of colour.
Feel free to contact me.
反曲点科技创始人和首席执行官。
开发、设计与写作皆为所长。
热爱苹果、钟情色彩。
随时恭候 垂询