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

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中的某种特殊情况,还是我完全误解了语句的工作原理?

有帮助吗?

解决方案

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

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

x and y返回y如果x是truish,x如果x是falsish; a or b,反之亦然,返回a如果它的truish,否则b

因此,如果port == "443"为真,这将返回and,即"https://"的RHS。否则,and是假的,所以or进入游戏,并返回` “HTTP://”,的及其的RHS

在现代Python中,一个更好的方式做翻译这个老十岁上下的成语是:

"https://" if port == "443" else "http://"

其他提示

如果左边是真

and返回右边的操作数。如果左边是假or返回正确的操作。否则,他们都返回左操作数。它们与所述的聚结

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

在大多数情况下它有效, 除了 如果 XFalse -- 这导致了Python代码中的许多错误,所以在 Python常见问题解答, ,你会发现更正确的解决方案是 (C and [X] or [Y])[0] 因为具有单个元素的列表,无论其评估的布尔值如何,总是 True!例如: [None]TrueNone 不是。上面的OP示例有效,因为代表的字符串 X 不为空。

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

这是不推荐的丑陋的黑客。它的工作原理是因为andor的短路行为,他们返回他们的论据之一,而不是一个布尔值。使用这种技术使引入难以发现的错误的风险,所以不要在新的代码中使用它。

下面是的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://"

您可能希望在本文中的Python“和/或技巧”读了奇特而和或在Python 性质。这有点像C语言风格的语言在VBA或VB,或IIF()?:

这个建筑工程,因为它展现出来的“到下面的代码:

a和b - >

if a:
  return b
else:
  return a

a或b - >

if a:
  return a
else:
  return b

所有好的答案,我发现这些发言帮助我记得这个更好的和适合我的大脑的工作(并希望对于一些更有):

  • "和"返回的第一个假项目(例如,没有, "", [], (), {}, 0) 或者最后一个项目,如果没有(例如没有虚假发)

  • "或者"返回的第一个真正的项目或者最后一个项目(例如没有真正发现的)**

在摘要:

  • 他们所返回的第一项决定的结果的声明。(在最糟糕的是,最后一个项目的顺序)

注意到这条规则也适用于一个链接"和"或者"或"声明

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top