内容简介: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的感知,即:全局唯一,且其内容最好也不要变化。所以在实际开发中,并不喜欢这种做法。
总结
从个人的倾向来看,比较喜欢「掌握一种或两种方式,然后使用最熟练,而且不出错」的观点,所以我只推荐第一二种方式。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Spring Into HTML and CSS
Molly E. Holzschlag / Addison-Wesley Professional / 2005-5-2 / USD 34.99
The fastest route to true HTML/CSS mastery! Need to build a web site? Or update one? Or just create some effective new web content? Maybe you just need to update your skills, do the job better. Welco......一起来看看 《Spring Into HTML and CSS》 这本书的介绍吧!