内容简介:Python 中 Singleton 的写法及其拓展
重要性无需多言,我们在项目中经常有「要一个进程全局的变量(内存块)」的需求,而且单例模式是几种 设计模式 中最容易的。
偷懒且有用的做法:模块级别常量
我经常使用这种方式,因为简单且不易出错。
众所周知,Python 的 module 概念,是一个天然的 Singleton。而且 Python 是多范式语言,可以不必像 Java 那样使用 class 去处理这件事情,在 module 级别定义一个常量,是一种很自然的想法。
代码如下:
- 定义方
singleton.py class _MySingleton(object): """ 我们使用下划线开头, 告诫调用者, 不要直接 new 也不要来访问这个class """ def __init__(self, name, age): self._name = name self._age = age def print_name(self): print(self._name) # 可以定制多个全局实例 S1 = _MySingleton('s1', 22) S2 = _MySingleton('s2', 11)
- 调用方
caller.py from singleton import S1 # 尽情使用S1( 在任意点import 都可以 ), 它是全局唯一的!
正规做法:元编程
有些人不喜欢上面那种做法,他们认为「破坏了代码的纯粹性」,这个时候我们可以使用元编程的方式,让我们更近一步。
这是从 Python Cookbook 摘取出来的代码。
- 元类基类
class SingletonMetaclass(type): def __init__(self, *args, **kwargs): self.__instance = None super().__init__(*args, **kwargs) def __call__(self, *args, **kwargs): if self.__instance is None: self.__instance = super(SingletonMetaclass, self).__call__(*args, **kwargs) return self.__instance else: return self.__instance
- 继承了元类基类的类
class SpamSingleton(metaclass=SingletonMetaclass): """注意: 根据Singleton的定义, 构造函数一般需要使用默认的构造函数""" def get_addr(self): return id(self)
- 调用方
from singleton import SpamSingleton s1 = SpamSingleton() s2 = SpamSingleton() pritn(id(s1), id(s2)) # 内存地址是一样的
老实说,理解 SingletonMetaclass 的作用过程还是有点困难的,我花了好久才搞清楚上面各个方法的调用流程。
不过 SingletonMetaclass 的作用也是巨大的,我们定义将其放入一个 base.py 的文件中,任何时刻我们想要定义某个 Singleton class,直接从其继承即可,简单且方便。
比较 Hack 的做法:Borg 模式
不多说,搜索引擎搜出来的结果,全都是推荐这种做法,让人以为这是「主流做法」(其实并不是)。
这种做法,修改了 Singleton 的定义,即:所有变量共享一个内存块,但是这个内存块的内容是可变化的。然后通过将实例的 __dict__
方法重定向 class 的 __dict__
方法,以达到其目的。
但是这种做法不是很符合我对 Singleton的感知,即:全局唯一,且其内容最好也不要变化。所以在实际开发中,并不喜欢这种做法。
总结
从个人的倾向来看,比较喜欢「掌握一种或两种方式,然后使用最熟练,而且不出错」的观点,所以我只推荐第一二种方式。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java Web整合开发王者归来
刘京华 / 清华大学 / 2010-1 / 99.80元
《Java Web整合开发王者归来(JSP+Servlet+Struts+Hibernate+Spring)》全面介绍了Java Web开发中的各种相关技术及知识。全书分为9篇,内容层次清晰,难度循序渐进。第1篇为入门篇,内容包括Java Web开发概述等;第2篇为基础篇,内容包括Servlet技术、JSP技术、会话跟踪、过滤器Filter、监听器Listener等;第3篇为高级篇,内容包括JST......一起来看看 《Java Web整合开发王者归来》 这本书的介绍吧!