Python条件语句中的括号

53

关于Python条件语句中括号的使用,我有一个简单的问题。

下面这两个片段的作用相同,但我想知道是否只因其简单而如此:

>>> import os, socket
>>> if ((socket.gethostname() == "bristle") or (socket.gethostname() == "rete")):
...     DEBUG = False
... else:
...     DEBUG = True
... 
>>> DEBUG

现在不使用括号

>>> import os, socket
>>> if socket.gethostname() == "bristle" or socket.gethostname() == "rete":
...     DEBUG = False
... else:
...     DEBUG = True
... 
>>> DEBUG

谁能帮忙解释一下?有哪些情况下我一定要使用它们吗?

7个回答

53

其他答案指出比较在布尔运算之前发生是完全正确的。作为替代方案(适用于像您演示的情况),您还可以使用以下方法来组合条件:

if socket.gethostname() in ('bristle', 'rete'):
  # Something here that operates under the conditions.

这样可以避免分别调用socket.gethostname,使得您在项目不断增长或需要授权其他主机时更加容易添加其他可能的有效值。


4
这并没有回答关于 Python 条件语句中括号的使用问题。 - The Godfather
4
@TheGodfather - 请您再说一遍?语句“比较在布尔运算之前进行”解释了在这种情况下使用这些括号是不必要的。接下来,它提供了一个更清晰、更易读的实现方法。这个做法已经被接受了将近9年了。 - g.d.d.c

24

括号只是强制运算顺序的,如果在条件语句中还有其他部分,比如 and ,最好使用括号来表示这个 and 是与哪个 or 搭配的。

if (socket.gethostname() == "bristle" or socket.gethostname() == "rete") and var == condition:
    ...

为了区别于

if socket.gethostname() == "bristle" or (socket.gethostname() == "rete" and var == condition):
    ...

13

在这种情况下,括号是多余的。比较运算符的优先级高于布尔运算符,因此无论是否使用括号都将首先执行比较。

话虽如此,我曾经看过一个指南(也许在《Practical C Programming》中),大致是这样说的:

  1. 首先进行乘法和除法
  2. 其次进行加法和减法
  3. 对其他所有内容使用括号

(是的,如果我没记错,他们忽略了指数!)

这意味着优先级规则足够晦涩,以至于不应该期望任何人都能记住它们,无论是原始程序员还是维护代码的程序员,因此最好使其明确化。基本上,括号既用于向编译器传达意图,也用作下一个使用该代码的人的文档。

我相信在Python中,这两个语句将生成相同的字节码,因此您甚至不会失去任何效率。


1
C的运算符优先级很奇怪。Python的却不是这样。因此,在Python中,括号并不像在C中那么常用。 - user395760
2
但是也有Python习语“显式优于隐式”。如果可能存在混淆的情况,就将它们加入其中。 - Wilduck
2
是的,C语言比Python更奇怪一些。不过,尝试在使用多种编程语言时保持它们的区分可能本身就会导致困惑。 - kindall

13

我一直认为这是PEP8的一部分,但实际上不是。然而,在所有PEP、代码示例和文档中遇到的示例中,你从来没有看到冗余的括号(例如在PyCharm中甚至有这样的检查)。

一般建议仅在括号能提高可读性或者确实需要改变表达式计算顺序时使用它们(例如(a or b) and c)。

要做到:

  if (first_expr or second_expr) and third_expr:    

  if first_expr or second_expr:

不要:

  if ((first_expr or second_expr) and third_expr):    

  if (first_expr):

  if (first_expr or (second_expr and third_expr)):
在你的代码示例中,括号是完全多余的,只需使用if socket.gethostname() == "bristle" or socket.gethostname() == "rete":(在生产代码中,当然,in会更可读,但现在这已经偏离主题了)。

2
在Python和许多其他编程语言中,每个具有多个运算符的表达式都不需要使用括号。这是因为运算符有一个定义好的优先级。在Python中,可以查看此处(第5.15节)的表格了解运算符优先级的信息。
可以将其类比于算术运算。以下表达式是等价的:
5 * 5 + 3

(5 * 5) + 3

如果你想先加三个数,那么你需要使用括号,像这样:

5 * (5 + 3)

0

我刚遇到了一个类似的问题。我的条件语句是

if count1==0 & count2==0 & count3==0:

第一个结果是True,第二个是False,第三个是True。直觉上,这个条件语句的结果应该是true。然而,它是false。但是下面这个句子的结果是正确的;

if (count1==0) & (count2==0) & (count3==0): 

我仍然没有弄清楚为什么会发生这种情况。


这里的问题在于括号。如果你写count1==0 & False,你会发现这将得到True,因为0 & False的结果是0,而count1 == 0是一个真命题。 - mikesol
如果您有新的问题,请通过单击提问按钮来提出。如果它有助于提供上下文,请包含此问题的链接。- 来自审核 - Paul Brennan

0

请查看手册。您在列表中越靠前,运算符将会被后应用。"or"高于"==",因此,在这种特殊情况下答案是相同的。但是,为了可读性和确保准确性,我建议使用括号。


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