我的编程空间,编程开发者的网络收藏夹
学习永远不晚

一文详解Python中实现单例模式的几种常见方式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

一文详解Python中实现单例模式的几种常见方式

Python 中实现单例模式的几种常见方式

元类(Metaclass):

class SingletonType(type):
    """
    单例元类。用于将普通类转换为单例类。
    """
    _instances = {}  # 存储单例实例的字典
    def __call__(cls, *args, **kwargs):
        """
        重写 __call__ 方法。用于创建和返回单例实例。
        """
        if cls not in cls._instances:  # 如果类还没有实例化过
            cls._instances[cls] = super().__call__(*args, **kwargs)  # 则创建新实例并存储在字典中
        return cls._instances[cls]  # 返回字典中的实例
class MyClass(metaclass=SingletonType):
    """
    单例类。使用元类 SingletonType 将其转换为单例类。
    """
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        print(f"Hello, my name is {self.name}.")
# 创建 MyClass 的两个实例,应该是同一个对象
obj1 = MyClass("Alice")
obj2 = MyClass("Bob")
# 打印两个实例的内存地址,应该相同
print(hex(id(obj1)))  # 输出:0x7f8d94547a90
print(hex(id(obj2)))  # 输出:0x7f8d94547a90
# 调用两个实例的方法,输出应该相同
obj1.say_hello()  # 输出:Hello, my name is Alice.
obj2.say_hello()  # 输出:Hello, my name is Alice.

在上面的代码中,我们定义了一个名为 SingletonType 的元类,并将其用作 MyClass 的元类。在 SingletonType 类中,我们维护了一个 _instances 字典,用于存储每个类的唯一实例。在 __call__() 方法中,我们检查 _instances 字典,如果类尚未拥有实例,则创建一个新实例并添加到 _instances 中。最后,我们返回 _instances 中的实例。

MyClass 类中,我们定义了一个带参数的构造函数,并且使用 metaclass 参数来指定 SingletonType 元类。由于 MyClass 类使用 SingletonType 元类,因此它具有单例行为。在程序中,我们创建了 MyClass 的两个实例 obj1obj2,然后打印它们的内存地址以验证它们是否是同一个对象。最后,我们调用这两个实例的方法,输出应该相同。

装饰器(Decorator):

def singleton(cls):
    """
    单例装饰器。用于将普通类转换为单例类。
    """
    instances = {}  # 存储单例实例的字典
    def get_instance(*args, **kwargs):
        """
        获取单例实例的方法。
        """
        if cls not in instances:  # 如果类还没有实例化过
            instances[cls] = cls(*args, **kwargs)  # 则创建新实例并存储在字典中
        return instances[cls]  # 返回字典中的实例
    return get_instance
@singleton
class MyClass:
    """
    单例类。使用装饰器 singleton 将其转换为单例类。
    """
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        print(f"Hello, my name is {self.name}.")
# 创建 MyClass 的两个实例,应该是同一个对象
obj1 = MyClass("Alice")
obj2 = MyClass("Bob")
# 打印两个实例的内存地址,应该相同
print(hex(id(obj1)))  # 输出:0x7f8d94547a90
print(hex(id(obj2)))  # 输出:0x7f8d94547

在上面的代码中,我们定义了一个名为 singleton 的装饰器函数。在 singleton 函数内部,我们创建了一个 instances 字典,用于存储每个类的唯一实例。然后,我们定义了一个名为 get_instance 的内部函数,用于获取单例实例。在 get_instance 函数中,我们检查 instances 字典,如果类尚未拥有实例,则创建一个新实例并添加到 instances 中。最后,我们返回字典中的实例。

MyClass 类上应用 @singleton 装饰器,以将其转换为单例类。由于该装饰器是针对类进行操作的,因此它可以轻松地将任何普通类转换为单例类。在程序中,我们创建了 MyClass 的两个实例 obj1obj2,然后打印它们的内存地址以验证它们是否是同一个对象。最后,我们调用这两个实例的方法,输出应该相同。

模块(Module):

# mymodule.py
class MyClass:
    """
    单例类。
    """
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        print(f"Hello, my name is {self.name}.")
my_singleton = MyClass("Alice")  # 创建单例实例
# main.py
from mymodule import my_singleton
# 使用单例实例
my_singleton.say_hello()  # 输出:Hello, my name is Alice.

在上面的代码中,我们将 MyClass 类定义在一个独立的模块 mymodule.py 中,并在其中创建了一个单例实例 my_singleton。然后,在另一个文件 main.py 中,我们从 mymodule 模块中导入 my_singleton 实例,并使用它来调用 say_hello() 方法。

由于 Python 模块在首次导入时会自动执行,因此我们可以利用这一特性来创建单例实例。在 mymodule.py 模块中,我们可以确保 my_singleton 只会被创建一次,并在程序的其他部分中共享它。

new 方法:

class MyClass:
    """
    单例类。
    """
    _instance = None  # 存储单例实例的类变量
    def __new__(cls, *args, **kwargs):
        """
        重写 __new__ 方法。用于创建和返回单例实例。
        """
        if cls._instance is None:  # 如果类还没有实例化过
            cls._instance = super().__new__(cls)  # 则创建新实例并存储在类变量中
        return cls._instance  # 返回类变量中的实例
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        print(f"Hello, my name is {self.name}.")
# 创建 MyClass 的两个实例,应该是同一个对象
obj1 = MyClass("Alice")
obj2 = MyClass("Bob")
# 打印两个实例的内存地址,应该相同
print(hex(id(obj1)))  # 输出:0x7f8d94547a90
print(hex(id(obj2)))  # 输出:0x7f8d94547a90
# 调用两个实例的方法,输出应该相同
obj1.say_hello()  # 输出:Hello, my name is Alice.
obj2.say_hello()  # 输出:Hello, my name is Alice.

在上面的代码中,我们将 MyClass 类的构造函数改为 __new__() 方法,并使用 _instance 类变量来存储单例实例。在 __new__() 方法中,我们检查 _instance 变量,如果类尚未拥有实例,则创建一个新实例并添加到 _instance 中。最后,我们返回 _instance 中的实例。

在程序中,我们创建了 MyClass 的两个实例 obj1obj2,然后打印它们的内存地址以验证它们是否是同一个对象。最后,我们调用这两个实例的方法,输出应该相同。

无论使用哪种方法实现单例模式,都需要注意线程安全和可扩展性等方面的问题。因此,在实际开发中,请仔细考虑自己的需求并选择合适的实现方式。

以上就是一文详解Python中实现单例模式的几种常见方式的详细内容,更多关于Python 单例模式的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

一文详解Python中实现单例模式的几种常见方式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

一文详解Python中实现单例模式的几种常见方式

这篇文章主要为大家介绍了Python中实现单例模式的几种常见方式示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-22

java中常见的几种单例模式

这篇文章主要为大家展示了“java中常见的几种单例模式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java中常见的几种单例模式”这篇文章吧。  单例模式:是一种常用的软件设计模式,在它的核心结
2023-06-19

在Java中,如何实现单例模式?有哪些实现方式?(请列举并解释Java中实现单例模式的几种常见方法。)

Java中单例模式确保一个类只有一个实例,用于控制资源访问、保持状态或提供全局访问点。实现方式包括:饿汉式:加载类时创建实例(线程安全,但浪费资源)。懒汉式:需要时创建实例(节省资源,但线程不安全,需同步)。双重检查锁定:优化懒汉式,使用volatile防止指令重排序(线程安全,性能较好)。枚举单例:利用枚举天生单例性和线程安全性。静态内部类:延迟加载,利用静态内部类确保单例性。
在Java中,如何实现单例模式?有哪些实现方式?(请列举并解释Java中实现单例模式的几种常见方法。)
2024-04-02

5种Python单例模式的实现方式

本文为大家分享了Python创建单例模式的5种常用方法,供大家参考,具体内容如下 所谓单例,是指一个类的实例从始至终只能被创建一次。 方法1: 如果想使得某个类从始至终最多只有一个实例,使用__new__方法会很简单。Python中类是通过
2022-06-04

Python 中用多种方式实现单例模式

单例模式是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在,本文给大家分享Python 实现单例模式的五种写法,感兴趣的朋友一起看看吧
2022-11-16

Python实现单例模式的5种方法

目录基本介绍优缺点Python实现方式1,元类实现:方式2,继承实现:方式3,装饰器实现:方式4,模块实现:方式5,@classmethod实现单例模式:基本介绍一个对象只允许被一次创建,一个类只能创建一个对象,并且提供一个全局访问点。 单
2022-06-02

Python使用redis pool的一种单例实现方式

本文实例讲述了Python使用redis pool的一种单例实现方式。分享给大家供大家参考,具体如下: 为适应多个redis实例共享同一个连接池的场景,可以类似于以下单例方式实现:import redis class RedisDBConf
2022-06-04

Golang sync.Once实现单例模式的方法详解

Go 语言的 sync 包提供了一系列同步原语,其中 sync.Once 就是其中之一。本文将深入探讨 sync.Once 的实现原理和使用方法,帮助大家更好地理解和应用 sync.Once,需要的可以参考一下
2023-05-18

详解Android中点击事件的几种实现方式

在之前博文中多次使用了点击事件的处理实现,有朋友就问了,发现了很多按钮的点击实现,但有很多博文中使用的实现方式有都不一样,到底是怎么回事。今天我们就汇总一下点击事件的实现方式。 点击事件的实现大致分为以下三种: (1)Activity 实现
2022-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录