找回密码
 立即注册
首页 业界区 业界 在Python中用any-singleton实现单例模式

在Python中用any-singleton实现单例模式

嗦或 昨天 00:05
单例模式

“单例”即在全局有且只有一个的实例,差不就类似于“全局变量”。
我个人常用类似以下的代码来实现单例模式:
  1. GLOBAL_KEY = '_my_coffee'
  2. if GLOBAL_KEY not in globals():
  3.     # 初始化:
  4.     globals()[GLOBAL_KEY] = {
  5.         'cup_of': 'tea'
  6.     }
  7. coff = globals()[GLOBAL_KEY]
  8. print(coff['cup_of'])  # Output: tea
复制代码
上面的coff就是一个单例,全局仅会初始化一次,并总是同一个对象。
至于其他的实现方法,这里不多做赘述。大家可以去看看站内的:Python中的单例模式的几种实现方式的及优化
Any-singleton

大部分情况下,单例模式可以很容易得被实现,并且正确运行。但总是要写一小段代码来实现,就不那么方便,也不易于管理。
为此,我就做了个简易的单例模式工具库——Any-singleton。
Any-singleton提供了两大功能:“创建单例”和“使函数仅运行一次”。
创建单例

我们仅需要调用singleton()并传入一个“唯一域名”和一个用于初始化的值,就可以很快的创建一个单例对象:
  1. from any_singleton import singleton
  2. tea = singleton('my_project.main.coffee', 'tea')
复制代码
当然,也可以不直接给一个值,而是利用singleton()实例化一个对象作为单例的初始值:
  1. from any_singleton import singleton
  2. my_range = singleton('my_project.main.coffee', range, 123)
复制代码
当第二个参数为一个type时,singleton()不会把该参数直接作为初始值,而是将其结合后面的参数实例化再作为初始值。
该单例的实例化过程在整个程序的生命周期将只会执行一次。


为了消除歧义,你还可以使用singleton_value()来替代singleton(),使之无论第二个参数是不是type类型的,都直接将其直接作为初始值使用:
  1. from any_singleton import singleton_value
  2. class Tea:
  3.     pass
  4. tea = singleton_value('my_project.main.coffee', type(Tea))
复制代码
使函数仅运行一次

使用@once()装饰器来创建一个在整个程序生命周期里只会被调用一次的函数:
  1. import tomllib
  2. from any_singleton import once, singleton
  3. @once('my_project.initializations.init')
  4. def init(config_path: str) -> None:
  5.     with open(config_path, 'rb') as f:
  6.         config = singleton('my_project.globals.config', tomllib.load(f))
  7. init('config.toml')
复制代码
或者使用@run_once()装饰器来创建一个被@once()装饰的函数,并立即自动调用一次。
  1. import tomllib
  2. from any_singleton import run_once, singleton
  3. @run_once(
  4.     'my_project.initializations.init',
  5.     second_calling = SecondCallingBehaviour.NoneToReturn,
  6.     # 以下的参数将传递给被装饰的`init()`。
  7.     'config.toml'
  8. )
  9. def init(config_path: str) -> None:
  10.     with open(config_path, 'rb') as f:
  11.         config = singleton('my_project.globals.config', tomllib.load(f))
复制代码
基本的用法就是这些了。
更多内容可以去查看我已经在PyPI上发布的any-singleton。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册