【问题标题】:Using None as parameter to keyword argument [duplicate]使用无作为关键字参数的参数[重复]
【发布时间】:2012-11-08 11:11:21
【问题描述】:

可能重复:
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. 在构造函数中创建一个对象实例,其值为默认值

这两种方法似乎都有些繁琐,有什么更简单的方法?

为某事设定价值

【问题讨论】:

  • 我喜欢链接,因为它可以将 300 行短代码更改为 100 行,具有相同或更高的可读性。
  • 不错的举动,在我写完答案后删除您的评论..

标签: python chaining


【解决方案1】:

您需要使用哨兵来检测未设置默认值:

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 = {}

【讨论】:

  • 从重复问题中复制您的答案是discouraged
【解决方案2】:

使用哨兵对象值是相当普遍的;这就是图书馆在abcoll.py 中所做的:

   __marker = object()

   def pop(self, key, default=__marker):
       ...
       if default is self.__marker:

注意,sentinel 对象应该直接在类中定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    相关资源
    最近更新 更多