我在课堂上有一个功能:
def foo(self, value = None):
if value is None:
return self.value
self.value = value
return self
这是一个getter和setter合二为一,其优点是我可以链接这样的函数:
three = anInstanceOfMyClass.foo(3).bar().foo()
当我这样做时会出现问题:
shouldBeNoneButIsThree = anInstanceOfMyClass.foo(3).foo(None).foo()
这里foo认为我没有通过论证。 我可以通过以下方式避免这种情况:
两者似乎都有点太多工作,更简单的方法是什么?
将值设置为某物
答案 0 :(得分:6)
您需要使用标记来检测未设置默认值:
sentinel = object()
def foo(self, value=sentinel):
if value is not sentinel:
print("You passed in something else!")
这是有效的,因为object()
的实例将始终拥有它自己的内存ID,因此is
只有在准确值保留的情况下才会返回True。 任何其他值都不会注册为同一个对象,包括None
。
您将在各种不同的python项目中看到上述技巧的不同变体。以下任何哨兵都可以使用:
sentinel = []
sentinel = {}
答案 1 :(得分:2)
使用sentinel对象值相当普遍;这就是图书馆在abcoll.py
中的作用:
__marker = object()
def pop(self, key, default=__marker):
...
if default is self.__marker:
请注意,sentinel对象应直接在类中定义。