“和”如何表达?和“或”合并在一个语句中时有效吗?
由于某种原因,这个函数让我感到困惑:
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中的某种特殊情况,还是我完全误解了语句的工作原理?
For some reason this function confused me:
def protocol(port):
return port == "443" and "https://" or "http://"
Can somebody explain the order of what's happening behind the scenes to make this work the way it does.
I understood it as this until I tried it:
Either A)
def protocol(port):
if port == "443":
if bool("https://"):
return True
elif bool("http://"):
return True
return False
Or B)
def protocol(port):
if port == "443":
return True + "https://"
else:
return True + "http://"
Is this some sort of special case in Python, or am I completely misunderstanding how statements work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这是一个古老的习语;插入括号以显示优先级,
如果
x
为真,则x 和 y
返回y
,如果x,则返回
是虚假的;x
a 或 b
,反之亦然,如果正确则返回a
,否则返回b
。因此,如果
port == "443"
为 true,则返回和
的 RHS,即"https://"
。否则,and
为 false,因此or
发挥作用并返回“http://”,其 RHS。在现代 Python 中,翻译这个古老习语的更好方法是:
It's an old-ish idiom; inserting parentheses to show priority,
x and y
returnsy
ifx
is truish,x
ifx
is falsish;a or b
, vice versa, returnsa
if it's truish, otherwiseb
.So if
port == "443"
is true, this returns the RHS of theand
, i.e.,"https://"
. Otherwise, theand
is false, so theor
gets into play and returns `"http://", its RHS.In modern Python, a better way to do translate this old-ish idiom is:
如果左侧操作数为 true,则
and
返回右侧操作数。如果左操作数为 false,则or
返回右操作数。否则它们都返回左操作数。据说它们合并。and
returns the right operand if the left is true.or
returns the right operand if the left is false. Otherwise they both return the left operand. They are said to coalesce.您真正要问的是像 C 和 X 或 Y 这样的表达式的含义或作用。这是Python 用户长期运行的早期尝试来代理
C 吗? X : Y
大部分情况下它都可以工作,除非如果
X
为False
——这导致了 Python 中的许多错误代码,所以在 Python FAQ,您会发现更正确的解决方案是(C和[X]或[Y])[0]
,因为列表包含单个元素,无论其评估的布尔值如何值,始终为True
!例如:[None]
是True
,但None
不是。上面的 OP 示例之所以有效,是因为表示X
的字符串不为空。然而,这一切在 Python 2.5 中都发生了变化,当三元或条件运算符被添加到语言中时,允许您使用更简洁的
X if C else Y
,如其他帖子中所述。如果您看到使用旧格式的代码,那是因为用户已经是长期 Python 程序员,尚未采用新语法,他们剪切粘贴其他旧代码,或者他们的雇主仍在使用 2.4.x (或更早版本)等等。总而言之,解决您的具体问题会带来一个也被使用的“隐藏功能”,所以让我们仔细看看
返回端口==“443”和“https://” " 或 "http://"
:and
的绑定比or
更强,这意味着您可以有效地想象此等效表达式中的一对括号:<代码>(端口==“443”和“https://”)或“http://”。此外,我提到的隐藏功能被称为短路,这样如果(端口==“443”和“https://”)都为真(它们确实如此),则< code>or 子句被完全忽略。但是,如果其中一个或都不为真,则这是唯一一次使用or
子句。另一个观察结果:非空字符串总是
True
,因此port == "443"
是唯一可能为False
的东西,所以这是所提出的主要问题。如果为 true,则计算将移至and
右侧,这意味着返回"https://"
。如果为 false,则会发生另一个短路,其中"https://"
被跳过,并且评估继续到or
的右侧。该代码的底线是:它检查是否
port == "443"
,如果是,则返回"https://
",否则 <返回代码>“http://”。True
和False
都可能不是返回值。最准确的等价形式是:在现代 Python 中,您可以这样写:
最后一个假设是
port
是一个字符串。更强大的版本将支持整数输入,例如,return "https://" if str(port) == "443" else "http://"
。What you are really asking is what an expression like
C and X or Y
means or does. It is the long-running early attempt by Python users to proxy forC ? X : Y
For the most part it works, except if
X
isFalse
-- this has led to many bugs in Python code, so in the Python FAQ, you'll find the more correct solution being(C and [X] or [Y])[0]
because a list with a single element, regardless of its evaluated Boolean value, is alwaysTrue
! For example:[None]
isTrue
butNone
isn't. The OP's example above works because the string representingX
is not empty.However, all this changed in Python 2.5, when the ternary or conditional operator was added to the language, allowing you to use the cleaner
X if C else Y
as stated in other posts here. If you see code using the older format, it's because the user has been a long time Python programmer who hasn't adopted the new syntax yet, they cut-n-paste other old code, or their employer is still using 2.4.x (or earlier releases), etc.All that said, addressing your specific question brings up a "hidden feature" that's employed as well, so let's take a closer look at
return port == "443" and "https://" or "http://"
:The
and
binds stronger than theor
, meaning you can effectively imagine a pair of parentheses in this equivalent expression:(port == "443" and "https://") or "http://"
. Furthermore, the hidden feature I referred to is known as a short circuit such that if both (port == "443" and "https://") are true (which they are), theor
clause is completely ignored. However if one or neither are true, that's the only time theor
clause will be used.Another observation: non-empty strings are always
True
, soport == "443"
is the only thing that can possibly beFalse
, so it is the main question being asked. If it is true, then evaluation moves to the right of theand
, meaning"https://"
is returned. If it is false, another short circuit happens where"https://"
is skipped, and evaluation continues to the right of theor
.Bottom-line for what the code does: it checks whether
port == "443"
, and if it is, then"https://
" is returned, otherwise"http://"
is returned. NeitherTrue
norFalse
are possibly return values. The most accurate equivalent is:In modern Python, you would write it like this:
One last assumption is that
port
is a string. A more robust version would support integer input, e.g.,return "https://" if str(port) == "443" else "http://"
.这是一个丑陋的黑客行为,不推荐。它之所以有效,是因为
and
和or
的短路行为,并且它们返回其参数之一而不是布尔值。使用此技术可能会带来引入难以发现的错误的风险,因此不要在新代码中使用它。下面是一个示例,说明
and/or
习惯用法如何产生意外结果:更喜欢使用较新的表示法:
This is an ugly hack that is not recommended. It works because of the short-circuiting behaviour of
and
andor
and that they return the one of their arguments rather than a boolean value. Using this technique gives a risk of introducing hard-to-find bugs, so don't use it in new code.Here's an example of how the
and/or
idiom can give an unexpected result:Prefer instead the newer notation:
您可能想在这篇文章中阅读有关 Python 的“与/或技巧”And 的特殊本质和 Python 中的 Or。它有点像 VBA 或 VB 中的
IIF()
,或者 C 风格语言中的?:
。You may want to read up on the "and / or trick" of Python in this article The Peculiar Nature of And and Or in Python. It's a bit like the
IIF()
in VBA or VB, or?:
in C-style languages.这种构造之所以有效,是因为它“展开”为以下代码:
a 和 b -->
a或b-->
This construction works because it 'unfolds' to the following code:
a and b -->
a or b -->
有了所有好的答案,我发现这些陈述可以帮助我更好地记住这一点并适应我的大脑的工作方式(并希望有更多):
“and”返回第一个 False 项目(例如,None,“” , [], (), {}, 0) 或最后一项(如果没有)(例如,未找到 False)
“或”返回第一个 True 项或最后一项(例如,未找到 True)**
总而言之:
请注意,此规则也适用于链接的全“and”或全“or”语句
With all the good answers, I found these statements help me remember this better and fit how my brain works (and hopefully for for some more out there) :
“and" returns the first False item (e.g., None, “”, [], (), {}, 0) or the last item if none (e.g. no False found)
“or" returns the first True item or the last item (e.g. no True found)**
In summary:
Note this rule also applies to a chained all "and" or all "or" statement