跳转到主要内容

表示Python中特殊含义的各种对象

项目描述

概述

sentinels模块是一个小型实用工具,提供Sentinel类及其有用的实例。

什么是哨兵?

哨兵是具有特殊含义的对象。它们可以被看作是单例,但它们服务于在代码中拥有具有特殊含义的“特殊”值的需要(见下例)。

我为什么需要哨兵?

为例。此哨兵在导入sentinels时会自动提供

>>> from sentinels import NOTHING

假设你正在编写一个围绕Python字典的包装器,它支持一种特殊的方法,get_default_or_raise。此方法的行为类似于get,但当它不接收默认值且键不存在时,它将引发KeyError。你将如何实现此类功能?简单的方法是这样的

>>> class MyDict(dict):
...     def get_default_or_raise(self, key, default=None):
...         if key not in self and default is None:
...             raise KeyError(key)
...         return self.get(key, default)

或者甚至是这样的

>>> class MyDict(dict):
...     def get_default_or_raise(self, key, default=None):
...         returned = self.get(key, default)
...         if returned is None:
...             raise KeyError(key)
...         return returned

但上述两段代码的问题相同——在编写通用实用类时,我们不知道它以后将如何被使用。更重要的是,None可能是一个完全有效的字典值!

这就是NOTHING大显身手的地方

>>> class MyDict(dict):
...     def get_default_or_raise(self, key, default=NOTHING):
...         returned = self.get(key, default)
...         if returned is NOTHING:
...             raise KeyError(key)
...         return returned

然后,看这里!

语义

哨兵总是等于自身

>>> NOTHING == NOTHING
True

但永远不会等于另一个对象

>>> from sentinels import Sentinel
>>> NOTHING == 2
False
>>> NOTHING == "NOTHING"
False

复制哨兵返回相同的对象

>>> import copy
>>> copy.deepcopy(NOTHING) is NOTHING
True

当然,也包括序列化和反序列化

>>> import pickle
>>> NOTHING is pickle.loads(pickle.dumps(NOTHING))
True

支持者