5

我发现了什么:

Dive in to Python 中,我读到了 and 运算符的特殊性质,and以及or布尔运算符的短路求值如何通过与C 中的三元运算符非常相似的and-or 技巧更简洁地表达条件。

C:

result = condition ? a : b

Python:

result = condition and a or b

这似乎派上了用场,因为 lambda 函数在 Python 中仅限于单行,但它使用逻辑语法来表达控制流。

从 Python 2.5 开始, inline-if似乎已经成为一种更易读的 and-or 技巧的语法:

result = a if condition else b

所以我猜这是对可读性较差的和/或构造的pythonic替代品。即使我想嵌套多个条件,它看起来仍然很全面:

result = a if condition1 else b if condition2 else c

但是在一个充满不确定性的世界中,我经常发现自己编写了一些这样的代码来访问 abc :

result = a and hasattr(a, 'b') and hasattr(a.b, 'c') and a.b.c or None 

因此,在inline-if的帮助下,我可能可以摆脱一些andsors,从而产生一段可读性很强的代码:

result = a.b.c if hasattr(a, 'b') and hasattr(a.b, 'c') else None

我还在这个食谱中发现了一种有点神秘的方法来处理条件

result = (a, b)[condition] 

但这不会短路,如果条件结果不返回布尔值 0 或 1,则会导致各种错误。

我想知道的:

现在我想知道是否认为使用内联更可取/更pythonic -if如果向下兼容性不是一个问题,或者只是一个品味问题,以及在短路世界中的感觉如何评估?

更新

我刚刚意识到 inline-if 不仅仅是 and-or-trick 的语法糖,因为a在布尔上下文中为 false 时它不会失败。所以它可能更防故障。

4

4 回答 4

2

由于内联有一个特殊的语言结构if-else它可以满足您的需求,并且被引入以替换您提到的那些丑陋的解决方法,因此使用它是一个好主意。and特别是因为像-技巧这样的黑客or通常会有意想不到的极端情况/错误。

在这种情况下,例如and-技巧会失败:or

a = 0
b = 1
c = True and a or b

cwill be 1,如果您正在寻找,这不是您所期望的if-else语义。

那么,当有一种语言结构完全符合您的要求时,为什么还要使用错误的解决方法呢?

于 2011-02-28T13:25:40.427 回答
2

Pythonic 要做的事情是识别您何时将代码拉伸到可以塞进单个函数并仅使用普通函数的范围内。请记住,您无法lambda使用命名函数来完成任何事情。

当然,每个人的突破点都会有所不同,但如果你发现自己在写:

return a.b.c if hasattr(a, 'b') and hasattr(a.b, 'c') else None

太多,考虑只这样做:

try:
     return a.b.c
except AttributeError:
     return None
于 2011-02-28T13:30:16.027 回答
0

我宁愿明确说明我的代码在做什么。内联 if 非常明确地进行条件赋值,并且可读性确实很重要。如果和/或副作用被认为是可取的,则内联 if 将不会使其成为语言。

条件表达式的 pep 更详细地说明了选择该特定语法的原因,并专门讨论了和/或 hack:

http://www.python.org/dev/peps/pep-0308/

于 2011-02-28T13:25:13.073 回答
0

这是针对您提到的特定情况,但我认为大多数需要链接短路逻辑的情况都可以使用更优雅的解决方案来处理。这显然是一个口味问题,让我补充一下,如果你认为上面的内容比这更好,那就划掉吧:

try:
    foo = a.b.c

except AttributeError:
    print "woops"

在其他不太直接的情况下,将所有测试封装在一个函数中可能会大大提高可读性。

EDIT: by the way, duck typing.

于 2011-02-28T13:30:25.527 回答