全局单身汉:深入理解 Python 中的单例对象

这篇具有很好参考价值的文章主要介绍了全局单身汉:深入理解 Python 中的单例对象。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考

项目 描述
搜索引擎 Google 、Bing
Python 官方文档

描述

项目 描述
Python 解释器 3.10.6

单例对象

单例对象

在 Python 中,单例对象是一种设计模式,旨在确保在应用程序中只有一个特定类的实例。这意味着无论创建多少个该类的实例,都将始终引用相同的实例。

单例对象的优缺点

单例对象的优点
  1. 节约资源
    单例对象只有一个实例,可以减少内存占用和系统资源的使用,特别是在需要创建多个相同实例的场景下,使用单例对象可以显著减少系统开销,提升程序的性能和效率。

  2. 提供全局访问点
    由于单例对象只有一个实例,可以在程序中任何需要访问该对象的地方提供一个全局访问点,简化程序的逻辑和开发难度。

  3. 保证对象的唯一性
    由于单例对象只有一个实例,可以确保对象的唯一性,避免由于多个实例之间的状态变化导致程序出错的情况。

单例对象的缺点
  1. 违反了单一职责原则
    单例对象通常既充当了对象的创建者,又充当了对象的访问者,从而增加了对象的职责,使得代码难以理解和维护。

  2. 可能会导致全局变量污染
    由于单例对象提供了全局访问点,可能会导致在程序中过度使用全局变量,增加代码的耦合性和不可预测性。

单例对象的应用场景

  1. 数据库连接池
    在一个系统中,需要频繁地访问数据库,而每次访问数据库都需要进行连接和认证等操作,这样会严重影响系统性能。因此,可以使用单例模式来创建数据库连接池,使得连接对象只被创建一次,可以被多个线程重用,从而提高了系统的性能。

  2. 日志系统
    在一个系统中,需要记录各种事件和操作的日志,而这些日志可能需要在整个系统中被使用和查询。因此,可以使用单例模式来创建一个全局的日志系统,将日志写入一个文件或者数据库中,从而方便系统的管理和查询。

  3. 配置管理器
    在一个系统中,可能需要读取和管理各种配置信息,如数据库连接信息、服务器地址、认证信息等等。因此,可以使用单例模式来创建一个全局的配置管理器,方便系统的配置和管理。

  4. 线程池
    在一个系统中,可能需要创建多个线程来完成各种任务,而每次创建线程都需要一定的开销和资源。因此,可以使用单例模式来创建一个线程池,使得线程对象只被创建一次,可以被多个任务重用,从而提高了系统的性能。

  5. 状态管理器
    在一个系统中,可能需要管理各种状态信息,如用户登录状态、购物车状态、订单状态等等。因此,可以使用单例模式来创建一个全局的状态管理器,方便系统的状态管理和查询。

实现单例对象的多种方式

  1. 模块
    将实例化的对象定义为一个模块级别的变量,当第二次导入该模块时,将不会重新创建该对象,而是直接使用之前创建的对象。

  2. 装饰器
    使用一个装饰器函数将类装饰成单例类,装饰器函数通过保存一个类的实例来确保只有一个实例被创建并且提供全局访问点。

  3. 元类
    通过定义一个元类,在类被创建时控制其实例化过程,可以确保在程序中只存在一个类的实例。

Python 与单例对象

铺垫

id()

在 Python 中,id() 函数是一个内置函数,用于获取对象的身份标识。每个对象都有一个唯一的身份标识,用于标识 该对象在内存中的位置。id() 函数接受一个 对象 作为参数,并返回该对象的身份标识。

举个栗子

# 返回一个列表对象的内存地址
print(id([]))

# 返回一个数值字面量的内存地址
# Python 中,一切皆对象
print(id(369))

执行效果

2197257094528
2197313149328
关键字 is

在 Python 中,is 是一个关键字,用于比较两个对象的身份标识是否相同。is 运算符用于检查两个对象是否是同一个对象,即它们是否引用同一个内存地址中的对象。is 关键字的两个操作数若为同一个对象,则返回 True,否则返回 False

举个栗子

arr = []
arr1 = arr
num = 369

# 输出各个变量所处的内存空间地址
print(id(arr))
print(id(arr1))
print(id(num))

# 通过相等运算符判断内存空间地址是否相同
print(id(arr) == id(arr1))
print(id(arr) == id(num))

# 使用 is 关键字判断内存空间地址是否相同
print(arr is arr1)
print(arr is num)```

`执行效果`

```python
2505215018368
2505215018368
2505271997872
True
False
True
False
相等运算符

在 Python 中,相等运算符是 ==,用于比较两个对象的值是否相等。如果两个对象的值相等,则相等运算符返回 True,否则返回 False相等运算符会比较两个对象的值,而不会比较它们的身份标识(即内存地址)是否相同。因此,即使两个对象的身份标识不同,只要它们的值相等,相等运算符也会返回 True。对此,请参考如下示例:

arr = [1, 2, 3]
arr1 = [1, 2, 3]

# 分别输出两个列表所处的内存空间地址
print(id(arr))
print(id(arr1))

# 将两个列表作为 is 关键字的操作数
print(arr is arr1)

# 使用相等运算符对两个列表解析判断
print(arr == arr1)

执行效果

2477433456000
2477488503360
False
True

基本数据类型与单例对象

基本数据类型

基本数据类型指的是编程语言中最基本的数据类型,通常由语言本身提供支持,而不需要额外的库或模块。

在 Python 中,基本数据类型包括以下 四种

数据类型 描述 示例
数值类型(Number) 用于表示数值,包括整数、浮点数和复数等。 整数类型可以表示任意大小的整数,浮点数类型可以表示实数,复数类型可以表示具有实部和虚部的复数。
字符串类型(String) 由一系列字符组成,用于表示文本信息。 可以用字符串类型表示一个人的姓名、一篇文章的标题等等。
布尔类型(Boolean) 只有两个取值,TrueFalse,用于表示真值和假值。 在编写程序时,可以使用布尔类型来进行条件判断和逻辑运算。
空类型(NoneType) 表示一个空值或者空对象,通常用于表示一个不存在的值。 在 Python 中,如果没有显示指明函数的返回值,则函数默认将返回 None
关联

Python 中的基本数据类型都是不可变类型,且在程序运行期间只会创建一次,并且被存储在内存的固定位置,这种特性被称为缓存。因此,可以认为 Python 中的基本数据类型都是单例对象,即同一个数值、字符串、布尔值或者空值在内存中只有一份。

举个栗子

a = 1
b = 1

print(id(a))
print(id(b))
print(id(1))

执行效果

1870240153840
1870240153840
1870240153840

注:

需要注意的是,这个特性仅适用于 Python 中的 基本数据类型,对于 复合数据类型(如列表、字典等)并不适用。

a = []
b = []

print(id(a))
print(id(b))
print(id([]))

执行效果

1997399098752
1997460311808
1997457222656

单例对象的特点

进程隔离

不同的进程创建的单例对象是不同的。因为在 Python 中,不同的进程会拥有自己独立的进程空间,它们之间不会共享任何资源,包括内存、文件句柄、网络连接等等。因此,在不同的进程中创建的单例对象是完全独立的,它们不会相互干扰。

如果需要在多个进程中共享单例对象,可以使用一些特殊的机制来实现,如共享内存、消息队列等等。这些机制可以在不同的进程之间传递数据,并且可以保证数据的同步和一致性。在使用这些机制时,需要注意线程安全和进程安全的问题,避免出现竞态条件、死锁等问题。

全局访问

Python 内置的基本数据类型是单例对象,因为它们经常被使用且不可变,使用单例模式可以节省内存空间,减少对象的创建和销毁,提高程序的效率。同时,这些基本数据类型被设计为可被全局访问,因为它们是开发者在 Python 代码中最常用的数据类型之一,开发者需要在程序的不同部分共享这些数据类型的值,以方便实现程序的逻辑。为此,Python 将这些数据类型的实例作为全局单例对象进行管理,以便在程序中的任何位置都可以访问到它们。文章来源地址https://www.toymoban.com/news/detail-434579.html

到了这里,关于全局单身汉:深入理解 Python 中的单例对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域

    目录 python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域 1、先来看个问题吧: 2、引用 VS 拷贝: 3、增强赋值以及共享引用:

    2024年02月08日
    浏览(47)
  • Python中的单引号、双引号、三引号

    在Python中,引号内的内容都是字符串类型的。而引号又有单引号、双引号、三引号,具体的用法以及注意点如下:         单引号和双引号都是用来表示字符串,在一般情况下两者没有任何差别,下面两句输出的结果都是 今天天气真好!         单引号双引号可以相

    2024年02月08日
    浏览(37)
  • 深入理解Python中的math和decimal模块:数学基础与高精度计算实战【第104篇—math和decimal模块】

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在Python中, math 和 decimal 模块是处理数学运算的重要工具。 math 提供了一系列常见的数学函数,而 decimal 则专注于高精度的浮点数运算。本文

    2024年03月19日
    浏览(51)
  • Python 中的单下划线和双下划线

    哈喽大家好,我是咸鱼 当我们在学习 Python 的时候,可能会经常遇到单下划线 _ 和双下划线 __ 这两种命名方式 单下划线 _ 和双下划线 __ 不仅仅是只是一种简单的命名习惯,它们在 Python 中有着特殊的含义,对于代码的可读性和功能实现有着关键的作用。 那么今天我们来看一

    2024年02月05日
    浏览(42)
  • 【每日易题】七夕限定——单身狗问题以及进阶问题位运算法的深入探讨

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,在写这篇博客的前一天是七夕,也是中国传统的“情人节”,不知道各位脱单了吗?碰巧最近刷题时遇到了经典的单身狗问题想带大家深入探讨一下,如果没脱单的话不如继续学习吧,记住

    2024年02月11日
    浏览(50)
  • 深入理解MySQL中的Join算法

    本文已收录至GitHub,推荐阅读 👉 Java随想录 微信公众号:Java随想录 原创不易,注重版权。转载请注明原作者和原文链接 目录 什么是Join Index Nested-Loop Join Block Nested-Loop Join MRR BKA 总结 在数据库处理中,Join操作是最基本且最重要的操作之一,它能将不同的表连接起来,实现对

    2024年02月08日
    浏览(45)
  • 深入理解UML中的继承关系

    在面向对象的设计中,继承关系是构建清晰、可维护系统的关键。统一建模语言(UML)提供了一种标准化的方法来可视化这些关系。本文将深入探讨UML中的继承关系,并探讨它如何在代码中体现。 继承关系在UML中用于表示一个类(子类)“继承”另一个类(父类)的属性和行

    2024年01月17日
    浏览(40)
  • 深入理解JavaScript中的Proxy代理

    JavaScript中的Proxy代理是ES6中引入的一项强大功能,它允许我们拦截、修改和自定义对象的底层操作。通过使用Proxy,我们可以在对象的属性读取、赋值、函数调用等操作之前或之后执行自定义的行为。在本文中,我们将深入探讨Proxy代理的各种用法和功能。 Proxy是JavaScript的一

    2024年02月07日
    浏览(44)
  • 深入理解PyTorch中的NoamOpt优化器

    作者:安静到无声 个人主页 今天,我们将深入探讨一个在自然语言处理领域广泛使用的优化器——NoamOpt。这个优化器是基于PyTorch实现的,并且在\\\"Attention is All You Need\\\"这篇论文中首次提出。 NoamOpt是一种特殊的学习率调度策略,它结合了两种不同的学习率调度方法:线性预热

    2024年02月13日
    浏览(48)
  • 深入理解Node.js中的Buffer

    109. 深入理解 Node.js 中的 Buffer Buffer 是 Node.js 核心库中的一个关键模块,用于处理二进制数据。在本文中,我们将深入探讨 Buffer 的概念、其在 Node.js 中的应用以及如何将 Buffer 转换为正常的数据。 1. Buffer 概述 Buffer 是 Node.js 中的一个全局对象,用于处理二进制数据流。它类似

    2024年02月16日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包