【面试】在Python中如何实现单例模式

点评:单例模式是指让一个类只能创建出唯一的实例,这个题目在面试中出现的频率极高,因为它考察的不仅仅是单例模式,更是对Python语言到底掌握到何种程度,建议大家用装饰器和元类这两种方式来实现单例模式,因为这两种方式的通用性最强,而且也可以顺便展示自己对装饰器和元类中两个关键知识点的理解。

**方法一:**使用装饰器实现单例模式。

from functools import wraps

def singleton(cls):

"""单例类装饰器"""

instances = {}

@wraps(cls)

def wrapper(*args, **kwargs):

if cls not in instances:

instances[cls] = cls(*args, **kwargs)

return instances[cls]

return wrapper

@singleton

class President:

pass

扩展:装饰器是Python中非常有特色的语法,用一个函数去装饰另一个函数或类,为其添加额外的能力。通常通过装饰来实现的功能都属横切关注功能,也就是跟正常的业务逻辑没有必然联系,可以动态添加或移除的功能。装饰器可以为代码提供缓存、代理、上下文环境等服务,它是对设计模式中代理模式的践行。在写装饰器的时候,带装饰功能的函数(上面代码中的wrapper函数)通常都会用functools模块中的wraps再加以装饰,这个装饰器最重要的作用是给被装饰的类或函数动态添加一个__wrapped__属性,这个属性会将被装饰之前的类或函数保留下来,这样在我们不需要装饰功能的时候,可以通过它来取消装饰器,例如可以使用President = President.__wrapped__来取消对President类做的单例处理。需要提醒大家的是:上面的单例并不是线程安全的,如果要做到线程安

全,需要对创建对象的代码进行加锁的处理。在Python中可以使用threading模块的RLock对象来提供锁,可以使用锁对象的acquire和release方法来实现加锁和解锁的操作。当然,更为简便的做法是使用锁对象的with上下文语法来进行隐式的加锁和解锁操作。

**方法二:**使用元类实现单例模式。

class SingletonMeta(type):

"""自定义单例元类"""

def init(cls, *args, **kwargs):

cls.__instance = None

super().init(*args, **kwargs)

def call(cls, *args, **kwargs):

if cls.__instance is None:

cls.__instance = super().call(*args, **kwargs)

return cls.__instance

class President(metaclass=SingletonMeta):

pass

扩展:Python是面向对象的编程语言,在面向对象的世界中,一切皆为对象。对象是通过类来创建的,而类本身也是对象,类这样的对象是通过元类来创建的。我们在定义类时,如果没有给一个类指定父类,那么默认的父类是object,如果没有给一个类指定元类,那么默认的元类是type。通过自定义的元类,我们可以改变一个类默认的行为,就如同上面的代码中,我们通过元类的__call__魔术方法,改变了President类的构造器那样。

补充:关于单例模式,在面试中还有可能被问到它的应用场景。通常一个对象的状态是被其他对象共享的,就可以将其设计为单例,例如项目中使用的数据库连接池对象和配置对象通常都是单例,这样才能保证所有地方获取到的数据库连接和配置信息是完全一致的;而且由于对象只有唯一的实例,因此从根本上避免了重复创建对象造成的时间和空间上的开销,也避免了对资源的多重占用。

再举个例子,项目中的日志操作通常也会使用单例模式,这是因为共享的日志文件一直处于打开状态,只能有一个实例去操作它,否则在写入日志的时候会产生混乱。

这个我还没完全弄懂,我懂了之后再来补充内容解释

相关推荐
程序员晚枫8 分钟前
Python文件类型大全:从.py到.pyd,你见过几种?
python
计算衎9 分钟前
python的AI大模型之facebook/nllb-200-distilled-600M的介绍和使用
人工智能·python·facebook·huggingface_hub
java_logo30 分钟前
BUSYBOX Docker 容器化部署指南
java·运维·python·nginx·docker·容器·运维开发
@老蝴1 小时前
Java EE - 多线程下单例模式的设计
单例模式·java-ee·intellij-idea
2501_941111821 小时前
使用Scikit-learn进行机器学习模型评估
jvm·数据库·python
小呀小萝卜儿2 小时前
2025-11-14 学习记录--Python-使用sklearn+检测 .csv 文件的编码+读取 .csv 文件
python·学习
Java水解2 小时前
20个高级Java开发面试题及答案!
spring boot·后端·面试
java1234_小锋2 小时前
[免费]基于python的Flask+Vue医疗疾病数据分析大屏可视化系统(机器学习随机森林算法+requests)【论文+源码+SQL脚本】
python·机器学习·数据分析·flask·疾病数据分析
乂爻yiyao3 小时前
设计模式思想——从单例模式说起
java·单例模式·设计模式
MediaTea3 小时前
Python 第三方库:cv2(OpenCV 图像处理与计算机视觉库)
开发语言·图像处理·python·opencv·计算机视觉