详解Python 单子的其他特性

  • Post category:Python

Python的单例模式是一种创建对象的方法,使得一个类只有一个实例化的对象,并且通过任何方式再次实例化该类时,都返回同一个对象。单例模式在一些对象必须是唯一的时候非常有用,例如连接数据库的类或操作系统的GUI控件。

Python的实现中有两种方式可以实现单例模式:第一种是使用模块(Module)作为单例模式的实现,第二种是使用类(Class)作为单例模式的实现。下面分别详细介绍这两种实现方式。

使用模块作为Python单例模式的实现

模块(Module)本质上也是单例模式的实现,每一个模块只会被加载一次,所以模块中的变量、方法等都只会有一个实例。通过使用Python的模块,我们可以很容易地实现单例模式。

下面是一个使用模块实现Python单例模式的示例代码:

# module.py

class Singleton(object):
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

class Example(Singleton):
    def __init__(self):
        self.data = []

example = Example()

该代码定义了一个Singleton类作为单例的基类,Example类从Singleton中继承,通过Example实现了一个实例化的单例对象example。因为Example是Singleton的子类,所以Example具有单例特性。

由于Python的模块本身就是一个单例对象,因此我们可以直接将Example单例的实现放到一个单独的模块中,并导入这个模块来使用单例对象,例如下面的代码:

# main.py
from module import example

print(id(example))  # 140674617571952
example.data.append(1)
print(example.data)  # [1]

from module import example as example2
print(id(example2))  # 140674617571952,同一个对象
example2.data.append(2)
print(example.data)  # [1, 2],两个变量都指向同一个对象

使用类作为Python单例模式的实现

Python单例模式的另一种实现是创建一个单例类。我们将该类的实例作为静态成员变量,并将该类的构造方法设为私有,确保不能从外部创建该类的任何实例。然后我们提供一个获取该类实例的静态方法,该方法用于返回该类的单例对象。

下面是一个使用类实现Python单例模式的示例代码:

class Singleton(object):
    _instance = None

    def __init__(self):
        if self._instance is not None:
            raise ValueError('An instance has already been created!')

    @classmethod
    def get_instance(cls):
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

class Example(Singleton):
    def __init__(self):
        super().__init__()
        self.data = []

example = Example.get_instance()

该代码创建了一个Singleton类作为单例的基类,并在单例类中定义了获取单例实例的静态方法get_instance()。Example类从Singleton继承,并通过调用get_instance()方法获取该类的单例实例。

需要注意的是,构造方法中有一个校验,确保每个类只能有一个实例。此外,也可以将校验移动到get_instance()方法中,在类被实例化的时候检查该类的实例是否已经存在,这样实现起来也非常简单。

接下来是一个使用类实现Python单例模式的示例代码:

example = Example.get_instance()
print(id(example))  # 140343781113232

example2 = Example.get_instance()
print(id(example2))  # 140343781113232,同一个对象

example.data.append(1)
print(example2.data)  # [1],两个变量都指向同一个对象

在这个示例中,我们可以看到,使用类实现Python单例模式的过程也非常简单,只需要将该类的构造方法设为私有,并通过单例方法获取该类的实例。