Python

Python如何实现单例模式?

文 / 大炳哥 来源 / 原创 阅读 / 9576 1年前

相关问题:

  1. 请说明什么是单例。
  2. 请说明单例在你工作中的场景
  3. 请用两种及以上的方式写出一个单例
  4. 请使用类装饰器完成一个单例模式

什么是单例模式

单例模式就是确保一个类只有一个实例。当你希望整个系统中,某个类只有一个实例时,单例模式就派上了用场。

单例模式的使用场景

例如,某个服务器的配置信息存在一个文件中,客户端通过AppConfig类来读取配置文件的信息。

如果程序的运行的过程中,很多地方都会用到配置文件信息,则就需要创建很多的 AppConfig实例,这样就导致内存中有很多AppConfig的实例对象,造成资源的浪费。如果我们能够保证 AppConfig的实例对象 只有一个,那我们就能解决这个问题。

实现单例模式的几种方法

1. 使用模块

python的模块就是天然的单例模式,因为模块在第一次导入的时候,会生成.pyc文件。当第二次导入的时候,就会直接加载.pyc文件,而不是再次执行模块代码。如果我们把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

# 创建单例

# mysingleton.py
class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()

# 使用单例

from singleton.mysingleton import singleton

2. 使用 __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

3. 使用装饰器实现单例模式

# 知识点复习

装饰器的作用:

装饰器,可以在不改变函数、类的原有功能的基础上添加新的功能。

# 思路

(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>
"""

4. 使用静态方法实现单例模式

# 知识点复习

静态方法,相当于普通的函数,不属于类方法,也不属于实例方法。

# 代码示例

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

评论

共0条评论
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~

站点声明:本站转载作品版权归原作者及来源网站所有,原创内容作品版权归作者所有,任何内容转载、商业用途等均须联系原作者并注明来源。

© 2019 The Pride & Joy of an Artisan. · Designed By duoguyu · Powered By Django京ICP备19006898号-1
相关侵权、举报、投诉及建议等,请发E-mail:lemont0086@163.com

友情链接: 大炳哥的博客 逐梦个人博客 微微的博客 daixu 十年之约