实现单例模式的几种方式

  import 是 Python 中的天然单例模式,我最先推荐这种方式。

  创建两个文件 signletion.py signletion_import.py,文件内容如下

复制代码
class User():
    def __new__(cls, *args, **kw):
        print("new instance")
        return super().__new__(cls, *args, **kw)

    def get(self):
        print("get class")


u = User()
u.get()
复制代码
from singletion import u

u.get()

# 输出结果:
# new instance
# get class
# get class

  运行结果只输出一次 new instance,代表只生成一个实例,创建单例成功,后续我们都用这种验证方式。

  

  

  使用 new 方法

  直接修改 __new__ 方法,类似 Java 的实现方式,实际开发中,我们可以在父类中实现方法,并继承

复制代码
class Singletion():
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            print("new instance")
            cls._instance = super().__new__(cls, *args, **kw)
        return cls._instance

class SingClass(Singletion):
    def get(self):
        print("get class")

c = SingClass()
c.get()

c1 = SingClass()
c1.get()

# 输出结果:
# new instance
# get class
# get class
复制代码

 

  

  使用装饰器

  装饰器是比较 Python 的方式,内部实现跟 __new__ 很像,判断已经有实例则不再生成。

复制代码
def singletion(cls):
    instance = {}
    def get_instance(*args, **kw):
        if cls not in instance:
            print("new instance")
            instance[cls] = cls(*args, **kw)
        return instance[cls]
    return get_instance

@singletion
class User():
    def get(self):
        print("get class")

u = User()
u.get()
u1 = User()
u1.get()

# 输出结果:
# new instance
# get class
# get class
复制代码

 

  

  使用元类

  元类同样是 Python 特有的,不过并不常用,我们可以利用它的特性来实现单例

复制代码
lass Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            print("new instance")
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class SingClass(metaclass=Singleton):
    def get(self):
        print("get class")

c = SingClass()
c.get()

c1 = SingClass()
c1.get()

# 输出结果:
# new instance
# get class
# get class
复制代码

  转自:https://wxnacy.com/2019/02/18/python-signletion/

posted @   阿布_alone  阅读(309)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
TOP
点击右上角即可分享
微信分享提示