重构 "x if x is not None else y" 为 "x or y"

4

我发现了一段 Python 代码,它的技术实现看起来像这样:

def bar(b):
    return b*2

class MyClass(object):
    def __init__(self, a):
        self.a = a
        self.b = 10

    def foo(self, b=None):
        return bar(b if b is not None else self.b)

所以这个类有一个固定的属性 b,它作为 classmethod foo 的默认输入参数,如果没有传入参数。请假设在这种情况下,b 应该是一个浮点数。
请忽略未使用的 self.a,它被用于其他地方 - 我只是想确保您看到构造函数设置了属性。
使用方法如下:
c = MyClass(2)
c.foo(3)  # returns 3*2 = 6
c.foo()  # returns 10*2 = 20

在这种情况下,我想知道foo方法是否是将b的默认值设置为self.b的好方法?
以下两个建议中的哪一个更理想?如果有的话:为什么?
def foo(self, b=None):
    return bar(b or self.b)

或者

def foo(self, b=self.b):
    return bar(b)
1个回答

9
坚持选择第一个选项:
def foo(self, b=None):
    return bar(b if b is not None else self.b)

如果您选择第二个选项:
def foo(self, b=None):
    return bar(b or self.b)

如果您将 x.foo(0) 的行为更改,那么零也会被视为 falsey。

第三个选项不可行:

def foo(self, b=self.b):
    return bar(b)

self在定义方法foo()时不存在,因此您不能将self.b用作默认参数。该定义将会失败;或者更糟糕的是,在执行定义时它将尝试使用self的当前值。


2
同意,虽然我可能会删除那个“not”:self.b if b is None else b - PM 2Ring
2
@PM2Ring 我认为,这取决于通常会发生什么。阅读 self.b if b is None else b 时,我假设传递参数 b 将会覆盖默认行为,即使用 self.b。而阅读 b if b is not None else self.b 时,我假设参数 b 被使用,但如果缺少该参数,则会使用默认值 self.b。结果是相同的,但语义不同。 - DainDwarf
公正的观点,@DainDwarf。我喜欢尽可能减少否定,因为这往往会使代码更易读(以及略微更有效)。但我想语义胜过这些考虑。 - PM 2Ring
没错。我还没有测试我的建议,所以我没有注意到第二个建议无法编译。此外,0被评估为False也是一个很好的观点(尽管在这个例子中,“b”始终为正数)。 - Nras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接