为什么在这个python片段中允许使用分号?

can*_*dry 148 python

Python不保证使用分号来结束语句.那么为什么这个(下面)允许?

import pdb; pdb.set_trace()
Run Code Online (Sandbox Code Playgroud)

And*_*ron 202

Python 不需要使用分号来终止语句.如果您希望在同一行上放置多个语句,可以使用半冒号来分隔语句.

现在,为什么允许这样做?这是一个简单的设计决策.我不认为Python需要这种半冒号的东西,但是有人认为将它添加到语言会很好.

  • 我来到Python的背景是C,Obj-C,Javascript,PHP.我经常放一个(无用的)终结器; 在一条线的尽头.但幸运的是,Python原谅了我 (66认同)
  • 分号在django shell或调试器中非常有用,因此您可以在一行上编写一个小程序,稍后再重复. (33认同)
  • 它对于``timeit a = 5; A*a`` (15认同)
  • 这对于exec语句似乎很有用,例如exec('for a in [1,2,3]:print a; print a + 1') (11认同)
  • @endolith"timeit"是什么意思?`a = 2; a*a`没用,因为`a`仍然是2; 它必须是'a = 2; a*= a` (4认同)
  • 当我必须在没有脚本文件的情况下从命令行运行一个简短的脚本时,分号对我来说非常有用。键入用分号分隔的多个表达式(`python -c "import time;t = time.time();print(int(t))"`)比使用换行符执行相同的操作更容易。 (4认同)
  • 如果你评估一个表达式的副作用,并且对表达式返回的内容不感兴趣,那么[在分号中很可能有分号](/sf/answers/2036582411/)(典型的例子,` matplotlib.pyplot`方法). (3认同)

cho*_*own 54

http://docs.python.org/reference/compound_stmts.html

复合语句由一个或多个"子句"组成.子句由标题和"套件"组成.特定复合语句的子句标题都在相同的缩进级别.每个子句头以唯一标识关键字开头,以冒号结束.套件是由子句控制的一组语句.套件可以是与标题位于同一行的一个或多个以分号分隔的简单语句,位于标题的冒号后面,也可以是后续行中的一个或多个缩进语句.只有后一种形式的套件才能包含嵌套的复合语句; 以下是非法的,主要是因为不清楚以下其他条款属于哪个if子句:

if test1: if test2: print x
Run Code Online (Sandbox Code Playgroud)

另请注意,在此上下文中,分号比冒号绑定更紧密,因此在以下示例中,执行所有打印语句或不执行任何打印语句:

if x < y < z: print x; print y; print z 
Run Code Online (Sandbox Code Playgroud)

总结:

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)* [";"]
Run Code Online (Sandbox Code Playgroud)

  • 在if之后不知道分号的优先级低于冒号.谢谢! (4认同)
  • @gaborous我个人认为你的评论含糊不清,让我觉得你的意思是另一种方式.因此,为了澄清,我宁愿建议其他读者坚持使用官方短语:在那个`if cond:stmt1; stmt2; stmt3`示例,执行全部或不执行任何语句".** (3认同)

kin*_*all 35

Python使用;as作为分隔符,而不是终结符.你也可以在行的末尾使用它们,这使它们看起来像一个语句终结符,但这只是合法的,因为空白语句在Python中是合法的 - 最后包含分号的行是两个语句,第二个一片空白.

  • 如果在末尾(或任何地方)放置双分号,则会出现SyntaxError.所以似乎空白的陈述并非完全合法. (25认同)
  • 可能它与列表具有相同的逻辑,元组,带尾随逗号的字符串是有效的,并且与它们的修剪对应物相同(例如[1,2,3] == [1,2,3,])但它们不能包含双逗号.所以基本上Python有一个"尾随空白移除器".从这一点可以清楚地看出:`stmt_list :: = simple_stmt(";"simple_stmt)*[";"]` (8认同)

gbo*_*ffi 24

解释器中的分号

阅读完答案之后,我仍然怀念使用分号的一个重要方面,可能是唯一一个真正有所作为的分号......

当您在解释器REPL(Python交互式shell,IDLE,ipython)中工作时,最后一个表达式的值将打印到屏幕上,通常这是预期的行为.

使用表达式的副作用

但在某些情况下,您只想评估表达式的副作用,例如,查看模拟的结果matplotlib.

在这种情况下,您(可能)不希望看到有时通过调用函数返回reprmatplotlib对象屏幕,matplotlib并且您可能的一种可能性是将分号附加到过于冗长的语句中,这就是由两个表达式,即matplotlib调用和一个空语句组成,因此复合表达式的值是,None并且解释器不会将任何内容打印到屏幕上(另一种可能是赋值,因为_ = plot(...)我发现它更具侵入性).

个人评论

恕我直言,在引入IPyton笔记本之后,使用分号来抑制解释器中不需要的输出变得更加相关,它允许保存解释器会话的输入和输出,包括图形输出,用于文档和最终重用.


Ben*_*Ben 12

正如其他人都注意到的那样,您可以使用分号来分隔语句.你不必到,这不是一贯的作风.

至于为什么这很有用,有些人喜欢在一行上放两个或两个以上非常简单的简短陈述(我个人认为这会将几个容易撇去的线条变成一个看起来很复杂的线条,这使得它更难以看出它是微不足道的) .

但是当你从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
Run Code Online (Sandbox Code Playgroud)

  • 您可以在外壳中通过python传递命令时使用缩进和换行符:只需将引用的代码跨越多行或使用heredoc。但是,如果您希望它成为“单线”,那将失败。;) (2认同)

eSu*_*ake 9

我意识到我作为一个老 C 程序员有偏见,但有时各种 Python 约定使事情难以遵循。我发现缩进约定有时有点烦人。

有时,明确语句或块何时结束非常有用。标准 C 代码通常会读取如下内容:

for(i=0; i<100; i++) {
    do something here;
    do another thing here;
}

continue doing things;
Run Code Online (Sandbox Code Playgroud)

您在其中使用空格以获得很多清晰度 - 很容易看到循环结束的地方。

Python 确实允许您以(可选)分号终止。如上所述,这并不意味着要执行一个语句,然后是一个“空”语句。所以,例如,

print(x);
print(y);
Run Code Online (Sandbox Code Playgroud)

是相同的

print(x)
print(y)
Run Code Online (Sandbox Code Playgroud)

如果您认为第一个在每行末尾都有一个空语句,请尝试 - 按照建议 - 这样做:

print(x);;
Run Code Online (Sandbox Code Playgroud)

它会抛出一个语法错误。

就我个人而言,当您有大量带有许多参数和/或长命名参数的嵌套和函数时,我发现分号可以使代码更具可读性。所以,在我看来,这比其他选择要清楚得多:

if some_boolean_is_true:
    call_function(
        long_named_arg_1,
        long_named_arg_2,
        long_named_arg_3,
        long_named_arg_4
    );
Run Code Online (Sandbox Code Playgroud)

因为,对我来说,它让你知道最后一个 ')' 结束了一些跨越多行的“块”。

我个人认为 PEP 风格指南、执行它们的 IDE 以及“只有一种 Pythonic 做事方式”的信念有很多。如果你相信后者,那就去看看如何格式化数字:截至目前,Python 支持四种不同的方式来做到这一点。

我确信我会被一些顽固的人抨击,但编译器/解释器并不关心参数是长名称还是短名称,而且 - 但对于 Python 中的缩进约定 - 不关心空格。代码的最大问题是让另一个人(甚至经过几个月的工作后的你自己)清楚地了解正在发生的事情,事情开始和结束的地方等。


Dmi*_* B. 5

分号是有效语法的一部分:8.复合语句(《 Python语言参考》)


God*_*win 5

如果一行中包含多个语句,Python 允许您使用分号来表示语句的结尾。


Com*_*ake 5

引自" 当蟒蛇袭击 "

不要以分号终止所有语句.在Python中执行此操作在技术上是合法的,但除非您在一行上放置多个语句(例如,x = 1; y = 2; z = 3),否则完全没用.

  • @ AnirbanNag'tintinmj'在这种特殊情况下,我相信`x,y,z = 1,2,3`较慢,因为它会导致不必要的往返构建元组,然后立即解复它.(顺便说一句,我并不认为@communistpancake建议使用`x = 1; y = 2; z = 3`模式.我认为他/她只是举例说明分号是如何分隔的而不是终结者.) (4认同)
  • 为什么不``x,y,z = 1,2,3`? (3认同)
  • @AnirbanNag - 因为那将是多语句行的垃圾示例。 (2认同)