为什么此 Python 代码片段中允许使用分号?[关闭]
- 2025-03-05 09:18:00
- admin 原创
- 29
问题描述:
Python 不保证使用分号来结束语句。
那么为什么允许这种(以下)行为呢?
import pdb; pdb.set_trace()
解决方案 1:
Python 不需要分号来终止语句。如果您希望将多个语句放在同一行,可以使用分号来分隔语句。
那么,为什么允许这样做呢?这是一个简单的设计决定。我认为 Python 不需要这个分号,但有人认为有分号会很好,于是就把它添加到了语言中。
解决方案 2:
来自8.复合语句:
复合语句由一个或多个“子句”组成。子句由标题和“语句套件”组成。特定复合语句的子句标题都具有相同的缩进级别。每个子句标题都以唯一标识关键字开头,以冒号结尾。语句套件是由子句控制的一组语句。语句套件可以是与标题位于同一行、位于标题冒号后的一个或多个以分号分隔的简单语句,也可以是后续行中的一个或多个缩进语句。只有后一种形式的语句套件可以包含嵌套的复合语句;以下形式是非法的,主要是因为不清楚后面的else子句属于哪个if子句:
if test1: if test2: print x
还要注意,在这种情况下,分号比冒号绑定得更紧密,因此在下面的例子中,要么执行所有打印语句,要么不执行任何打印语句:
if x < y < z: print x; print y; print z
总结:
compound_stmt ::= if_stmt
| while_stmt
| for_stmt
| try_stmt
| with_stmt
| funcdef
| classdef
| decorated
suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement ::= stmt_list NEWLINE | compound_stmt
stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
解决方案 3:
Python 使用 来;
作为分隔符,而不是终止符。您也可以在行尾使用它们,这会使它们看起来像语句终止符,但这是合法的,因为空白语句在 Python 中是合法的——一行末尾包含分号的语句是两个语句,第二个语句为空白。
解决方案 4:
解释器中的分号
读完答案后,我仍然错过了使用分号的一个重要方面,这可能是唯一真正有区别的方面......
当您在解释器REPL(Python 交互式 shell、IDLE和IPython )中工作时,最后一个表达式的值会打印到屏幕上,通常这是预期的行为。
使用表达式来表示副作用
但在某些情况下,您只想评估表达式的副作用,例如,查看绘制的模拟结果matplotlib
。
在这种情况下,您(可能)不想看到有时通过调用函数返回的对象repr
屏幕,至少在 IPython 中,您可以选择的一种方法是将分号附加到过于冗长的语句,现在 IPython 将输入行视为由两个表达式组成,即调用和空语句,这样复合表达式的值就是,并且解释器不会在屏幕上打印任何内容(另一种可能性是赋值,如但我发现这有点更具侵入性)。matplotlib
`matplotlibmatplotlib
None`_ = plot(...)
个人评论
恕我直言,自从 IPython 笔记本推出之后,使用分号来抑制解释器中不需要的输出变得更加重要,它允许保存解释器会话的输入和输出(包括图形输出),以供文档记录和最终重用。
解决方案 5:
正如其他人所指出的,您可以使用分号来分隔语句。您不必这样做,而且这不是通常的风格。
至于为什么这很有用,有些人喜欢将两个或多个真正琐碎的简短语句放在一行上(我个人认为这会将几行容易浏览的琐碎语句变成一行复杂的语句,并且更难看出它是琐碎的)。
但当你使用 从 shell 调用 Python 单行程序时,这几乎是必需的python -c '<some python code>'
。在这里你不能使用缩进来分隔语句,所以如果你的单行程序实际上是两行,你需要使用分号。如果你想在单行程序中使用其他参数,你必须导入sys
才能获得sys.argv
,这需要一个单独的import
语句。例如
python -c "import sys; print ' '.join(sorted(sys.argv[1:]))" 5 2 3 1 4
1 2 3 4 5
解决方案 6:
我意识到自己作为一名老C程序员有偏见,但有时各种 Python 惯例会让事情变得难以遵循。我发现缩进惯例有时有点烦人。
有时,明确语句或块的结束时间非常有用。标准 C 代码通常会显示如下内容:
for(i=0; i<100; i++) {
do something here;
do another thing here;
}
continue doing things;
使用空白可以得到更清晰的效果 - 而且很容易看到循环的结束位置。
Python 确实允许您使用(可选的)分号终止。如上所述,这并不意味着要执行的语句后面跟着“null”语句。因此,例如,
print(x);
print(y);
等同于
print(x)
print(y)
如果您认为第一个在每一行末尾都有一个空语句,请尝试 - 按照建议 - 执行以下操作:
print(x);;
它将引发语法错误。
就我个人而言,我发现,当你有大量嵌套和带有许多参数和/或长命名参数的函数时,分号可以使代码更具可读性。所以,在我看来,这比其他选择要清晰得多:
if some_boolean_is_true:
call_function(
long_named_arg_1,
long_named_arg_2,
long_named_arg_3,
long_named_arg_4
);
因为,对我来说,它让你知道最后的')'结束了一些跨越多行的'块'。
我个人认为,PEP 风格指南、强制执行这些指南的 IDE 以及“只有一种 Python 式做事方法”的信念太过复杂了。如果您相信后者,请看看如何格式化数字:截至目前,Python 支持四种不同的格式化方法。
我确信我会被一些顽固分子痛骂,但编译器/解释器并不关心参数的名称是长还是短,而且 - 除了 Python 中的缩进约定 - 也不关心空格。代码的最大问题是让另一个人(甚至是经过数月工作的你自己)清楚地了解发生了什么,事情从哪里开始和结束,等等。
解决方案 7:
摘自《当蟒蛇进攻时》
不要用分号结束所有语句。在 Python 中这样做在技术上是合法的,但除非您在一行中放置多个语句(例如,x=1;y=2;z=3),否则完全没有用。
解决方案 8:
分号是有效语法的一部分:8. 复合语句(Python 语言参考)
解决方案 9:
如果一行中包含多个语句,Python 确实允许您使用分号来表示语句的结束。
解决方案 10:
一行中的多个语句可能包含分号作为分隔符。例如:8. 复合语句。对于您的情况,它可以轻松插入一个点以中断调试器。
此外,正如 Mark Lutz 在《学习 Python 手册》中提到的那样,用分号终止所有语句在技术上是合法的(尽管没有必要并且很烦人) 。
解决方案 11:
分号(“;”)仅用于分隔同一块内的语句,例如我们有以下 C 代码:
if(a>b)
{
largest = a; // Here 'largest' and 'count' are integer variables
count += 1;
}
在 Python 中它可以以以下两种形式编写:
if a > b:
largest = a
count = count + 1
或者
if a > b: largest = a; count = count + 1
在上面的例子中,你可以在一个if
块内拥有任意数量的语句,并且可以用“;”分隔。
我希望没有什么事情像上面的解释那么简单。
解决方案 12:
分号(如点、逗号和括号)容易引发宗教战争。不过,出于各种原因,它们(或一些类似符号)在任何编程语言中都很有用。
实用:能够将概念上属于同一行的多个短命令放在同一行上。看起来像一条窄蛇的程序文本与换行符和缩进的预期效果相反,即突出显示结构。
概念:将纯语法(在本例中为一系列命令)与表示(例如换行符)之间的关注点分离,在过去称为“漂亮的打印”。
观察:为了突出结构,可以以明显的方式用垂直线增强/替换缩进,作为“视觉标尺”,以查看缩进的开始和结束位置。不同的颜色(例如,遵循电阻器的颜色代码)可以补偿拥挤。
解决方案 13:
这是允许的,因为作者决定允许它:
6. 简单语句
如果要问为什么作者决定这样做,我猜是因为至少在以下语言中分号被允许作为简单的语句终止:C++、C、C#、R、MATLAB和Perl。
因此,对于有其他语言背景的人来说,使用 Python 会更快。而且这种决定不会失去通用性。
解决方案 14:
分号可用于一行两个或多个命令。它们不是必须使用,但不受限制。
分号(;)允许在一行上使用多个语句,但两个语句都不会开始新的代码块。
Python 基本语法
解决方案 15:
与Matplotlib库相关:
import numpy as np
import matplotlib as plt
%matplotlib notebook
linear_data = np.array([1, 2, 3, 4, 5, 6, 7, 8])
quadratic_data = linear_data**2
plt.figure()
xvals = range(len(linear_data))
plt.barh(xvals, linear_data, height = 0.3, color='b')
plt.barh(xvals, quadratic_data, height = 0.3, left=linear_data, color='r')
如果您没有在 barh(水平线)末尾提供分号,则输出是绘图 + 函数地址。但是,如果您在两个 barh 行末尾都使用分号,则它仅显示绘图并抑制函数地址的输出。
像这样:
比较