使用None作为关键字参数的参数

时间:2012-11-08 11:11:21

标签: python chaining

  

可能重复:
  python - returning a default value

我在课堂上有一个功能:

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认为我没有通过论证。 我可以通过以下方式避免这种情况:

  1. 将值设置为某个奇怪的对象,如随机字符串
  2. 在构造函数中创建一个对象实例,其值为默认值
  3. 两者似乎都有点太多工作,更简单的方法是什么?

    将值设置为某物

2 个答案:

答案 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对象应直接在类中定义。