博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python设计模式之单例模式
阅读量:5095 次
发布时间:2019-06-13

本文共 2081 字,大约阅读时间需要 6 分钟。

单例模式

单例模式需要注意的地方在于

  • 如何保证创建的实例是唯一的
  • 如何保证多线程情况下的访问
  • 清晰明了

目前有这么几种方法:

  1. module
  2. metaclass
  3. __new__
  4. decorator

module

其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:

  1. 首先在一个py文件中定义这么一个单例类:

    class Singleton(object):    def __init__(self):        self._val = 10    @property    def val(self):        return self._val    @val.setter    def val(self, val):        self._val = valsingleton = Singleton()
  2. 然后再在其它的文件中import

    from Singleton import singletonassert singleton.val == 10singleton.val = 20assert singleton.val == 20

但是这个有个缺点,就是程序一开始的时候就进行了创建,造成不必要的浪费,最好是在使用的时候才进行创建,还有另外一个缺点在于,如果有人不遵守规定使用已经创建好的实例,而是自己创建则无法实现单例。

metaclass

这正是元类可以做的事情-通过声明一个元类,我们告诉Python把类对象的创建路由到我们提供的另一个类,从而达到拦截类的创建的目的。用户唯一需要做的是,它们需要声明元类,每个这么做的都会自动获取到元类所提供的扩展。

class Singleton(type):    def __init__(cls, what, bases, dict):        super().__init__(what, bases, dict)        cls._instance = None    def __call__(cls, *args, **kwargs):        if cls._instance is None:            cls._instance = super().__call__(*args, **kwargs)        return cls._instanceclass MyClass(metaclass=Singleton):    passclass1 = MyClass()class2 = MyClass()assert class1 == class2

__new__

如果在子类中如果没有重载__new__方法,那么子类则会顺着继承关系,找到父类中的__new__,但是如果子类已经重载了,而且没有显式的调用父类的方法,那么就相当于再次进行重载,就不会再去调用父类的__new__方法,需要注意!

class Singleton(object):    _instance = None    def __new__(cls, *args, **kw):        if not cls._instance:            cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)        return cls._instanceclass MyClass(Singleton):    passclass1 = MyClass()class2 = MyClass()assert id(class1) == id(class2)

装饰器

在装饰器中,我们通过拦截它的__new__实现,判断它是否存在于该类的__dict__字典中,如果存在则返回,不存在则创建该类并且存放于__dict__中,并且进行相应的初始化。

def singleton(cls, *args, **kw):    instances = {}    def getinstance():        if cls not in instances:            instances[cls] = cls(*args, **kw)        return instances[cls]    return getinstance@singletonclass myclass:    passclass1 = myclass()class2 = myclass()assert class1 == class2

转载于:https://www.cnblogs.com/George1994/p/7106748.html

你可能感兴趣的文章
[13年迁移]Firefox下margin-top问题
查看>>
Zookeeper常用命令 (转)
查看>>
Enterprise Library - Data Access Application Block 6.0.1304
查看>>
重构代码 —— 函数即变量(Replace temp with Query)
查看>>
Bootstrap栅格学习
查看>>
程序员的数学
查看>>
聚合与组合
查看>>
洛谷 P2089 烤鸡【DFS递归/10重枚举】
查看>>
我眼中的技术地图
查看>>
lc 145. Binary Tree Postorder Traversal
查看>>
在centos上开关tomcat
查看>>
无人值守安装linux系统
查看>>
黑马程序员——2 注释
查看>>
android dialog使用自定义布局 设置窗体大小位置
查看>>
ionic2+ 基础
查看>>
查询消除重复行
查看>>
[leetcode]Minimum Path Sum
查看>>
内存管理 浅析 内存管理/内存优化技巧
查看>>
Json格式的字符串转换为正常显示的日期格式
查看>>
[转]Android xxx is not translated in yyy, zzz 的解决方法
查看>>