相关问题:
- 请说明什么是单例。
- 请说明单例在你工作中的场景
- 请用两种及以上的方式写出一个单例
- 请使用类装饰器完成一个单例模式
单例模式就是确保一个类只有一个实例。当你希望整个系统中,某个类只有一个实例时,单例模式就派上了用场。
例如,某个服务器的配置信息存在一个文件中,客户端通过AppConfig类
来读取配置文件的信息。
如果程序的运行的过程中,很多地方都会用到配置文件信息,则就需要创建很多的 AppConfig实例
,这样就导致内存中有很多AppConfig的实例对象
,造成资源的浪费。如果我们能够保证 AppConfig的实例对象
只有一个,那我们就能解决这个问题。
python的模块
就是天然的单例模式,因为模块在第一次导入的时候,会生成.pyc
文件。当第二次导入的时候,就会直接加载.pyc文件
,而不是再次执行模块代码。如果我们把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。
# 创建单例
# mysingleton.py
class Singleton(object):
def foo(self):
pass
singleton = Singleton()
# 使用单例
from singleton.mysingleton import singleton
__new__()
方法# 知识点复习
对象的实例化过程
先执行类的
__new__()
方法,如果我们没有重写,则默认调用object的__new__()
方法,返回一个实例化对象,然后再调用__init__()方法
,对这个对象进行初始化。
# 思路
在一个类的 __new__()
方法中,先判断是不是存在实例。如果存在实例,就直接返回;如果不存在,就创建实例。
# 代码示例
class AppConfig:
def __new__(cls, *args, **kwargs):
"""
若此类不存在 instance 属性,就创建并存储示例对象,再返回这个属性。
如果此类存在 instance 属性,就直接返回这个属性。
"""
if not hasattr(cls, 'instance'):
cls.instance = super().__new__(cls, *args, **kwargs)
return cls.instance
# 知识点复习
装饰器的作用:
装饰器,可以在不改变函数、类的原有功能的基础上添加新的功能。
# 思路
(1)装饰器外层函数中,定义一个字典变量,用来存储这个类的实例对象。
(2)每次创建对象的时候,都去这个字典中判断一下是否存在这个类的实例对象。如果存在,就直接取这个实例对象;如果不存在,就保存到字典中。
# 代码示例
def singleton(cls):
instance = {} # instance是标志位
def get_instance(*args, **kwargs):
# 判断cls是否在字典中
if cls not in instance:
instance[cls] = cls(*args, **kwargs) # 不存在,就创建
return instance[cls]
return get_instance
@singleton
class AppConfig:
pass
app_config = AppConfig()
print(app_config)
app_config = AppConfig()
print(app_config)
"""
输出结果:
<__main__.AppConfig object at 0x7fc9917d24c0>
<__main__.AppConfig object at 0x7fc9917d24c0>
"""
# 知识点复习
静态方法,相当于普通的函数,不属于类方法,也不属于实例方法。
# 代码示例
class AppConfig:
@staticmethod
def instance(cls, *args, **kwargs):
"""
若此类不存在 instance 属性,就创建并存储示例对象,再返回这个属性。
如果此类存在 instance 属性,就直接返回这个属性。
"""
if not hasattr(cls, 'instance'):
cls.instance = super().__new__(cls, *args, **kwargs)
return cls.instance
【了解】能够独立说出什么是单例模式。
单例模式就是确保一个类只有一个实例
【了解】能够独立说出工作中单例模式的使用场景。
重复使用的对象,可以通过单例模式减少内存的开销。
【掌握】能够独立的写出4中单例的方式代码
1. 模块方式
2. __new__()
3. 装饰器方式
4. 静态方法方法
12