12

由于某种原因,这个功能让我感到困惑:

def protocol(port):
    return port == "443" and "https://" or "http://"

有人可以解释幕后发生的事情的顺序,以使其按原样工作。

在我尝试之前,我是这样理解的:

A)

def protocol(port):
    if port == "443":
        if bool("https://"):
            return True
    elif bool("http://"):
        return True
    return False

或 B)

def protocol(port):
    if port == "443":
        return True + "https://"
    else:
        return True + "http://"

这是 Python 中的某种特殊情况,还是我完全误解了语句的工作原理?

4

7 回答 7

32

这是一个古老的成语;插入括号以显示优先级,

(port == "443" and "https://") or "http://"

x and yy如果x为真,x如果为假,则返回xa or b,反之亦然,a如果为真则返回,否则返回b

因此,如果port == "443"为真,则返回 的 RHS and,即"https://"。否则,and为假,因此or开始发挥作用并返回 `"http://",它的RHS。

在现代 Python 中,翻译这个古老的习语的更好方法是:

"https://" if port == "443" else "http://"
于 2010-04-05T17:50:41.117 回答
8

and如果左边为真,则返回右边的操作数。or如果左边为假,则返回右边的操作数。否则它们都返回左操作数。据说它们会合并

于 2010-04-05T17:50:25.220 回答
5

C and X or Y是 Python 用户长期尝试代理C ? X : Y

在大多数情况下,它可以工作,除非是- 这导致 Python 代码中出现许多错误,因此在XPython FAQ中,您会发现更正确的解决方案是因为具有单个元素的列表,而不管其评估的布尔值如何价值,永远是!例如:是但不是。上面的 OP 示例有效,因为表示的字符串不为空。False(C and [X] or [Y])[0]True[None]TrueNoneX

然而,这一切在 Python 2.5 中发生了变化,当三元或条件运算符被添加到语言中时,允许您使用X if C else Y此处其他帖子中所述的清洁器。如果您看到使用旧格式的代码,那是因为用户是长期没有采用新语法的 Python 程序员,他们剪切并粘贴了其他旧代码,或者他们的雇主仍在使用 2.4.x (或更早的版本)等。

于 2010-04-05T18:10:29.693 回答
2

这是一个不推荐的丑陋黑客。它之所以起作用,是因为 and 的短路行为,and并且or它们返回其参数之一,而不是布尔值。使用这种技术有引入难以发现的错误的风险,所以不要在新代码中使用它。

and/or以下是该成语如何产生意外结果的示例:

>>> foo = 'foobar'
>>> bar = 'foobar'
>>> x = 0
>>> y = 1
>>> (foo == bar) and x or y   # Will this return the value of x if (foo == bar)?
1

更喜欢更新的符号:

return "https://" if port == "443" else "http://"
于 2010-04-05T17:51:09.310 回答
1

您可能想在这篇文章The Peculiar Nature of And and or in Python 中阅读 Python 的“和/或技巧” 。这有点像IIF()VBA 或 VB 或?:C 风格的语言。

于 2010-04-05T17:52:27.803 回答
0

此构造有效,因为它“展开”为以下代码:

a 和 b -->

if a:
  return b
else:
  return a

a 或 b -->

if a:
  return a
else:
  return b
于 2010-04-05T17:55:03.587 回答
0

有了所有好的答案,我发现这些陈述可以帮助我更好地记住这一点,并适合我的大脑工作方式(希望还有更多):

  • “and” 返回第一个 False 项(例如,None、“​​”、[]、()、{}、0),如果没有则返回最后一项(例如,没有找到 False)

  • “或”返回第一个 True 项目或最后一个项目(例如未找到 True)**

总结

  • 它们都返回决定语句结果的第一个项目。(在最坏的情况下,序列中的最后一项)

请注意,此规则也适用于链接的所有“and”或所有“or”语句

于 2017-08-01T23:16:35.947 回答