基于__new__方法实现

这种方式适用于大多数语言

class Foo(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = object.__new__(cls)
        return cls._instance


obj1 = Foo()
obj2 = Foo()
print(id(obj1))   # 1947047481584
print(id(obj2))   # 1947047481584


SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

基于模块实现

基于模块实现是python特有的

原理

模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,
就可以获得一个单例对象了

新建一个package,在这个package里创建两个文件singleton.py和test.py

在singleton.py里写入以下内容

class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age


obj = Foo('张三丰', 88)



test.py里写入以下内容

from singleton import obj as obj1
print(obj1.name)                           # 张三丰

obj1.name = '张无忌'                       # 修改obj1的name属性,测试obj2是否会随之改变
print(obj1.name)                           # 张无忌

from singleton import obj as obj2

print(obj2.name)                           # 张无忌

print(id(obj1))                            # 2275441880032
print(id(obj2))                            # 2275441880032,id相同,说明是同一个对象

print(obj1 is obj2)                        # True



# 对比(不使用单例模式)
from singleton import Foo

obj3 = Foo('张三丰', 88)
obj4 = Foo('张三丰', 88)

print(id(obj3))                              # 2606272587200
print(id(obj4))                              # 2606272587144

print(obj3 is obj4)                      # False

可以看到obj1和obj2是同一个对象,这是由python模块的导入机制形成的。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄