命令行中的'if'语句和一行Python脚本

10 投票
4 回答
13493 浏览
提问于 2025-04-18 04:16

为什么我在运行下面这行Python代码时会收到语法错误?

python -c 'import re; if True: print "HELLO";'
  File "<string>", line 1
    import re; if True: print "HELLO";
                ^
SyntaxError: invalid syntax

下面这段代码运行得很好:

python -c 'if True: print "HELLO";'

我该如何修改我的这行代码,以便在命令行中一次性执行我想要的脚本呢?

4 个回答

2

为什么我在运行下面这行Python代码时会收到语法错误?

Python的语法规则可能不允许在代码中出现 small_stmt ';' compound_stmt 这种写法。-c 参数可能被解释为 file_input

fileinput: (NEWLINE | stmt)* ENDMARKER
stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: import_stmt <in this case>
compound_stmt: if_stmt <in this case>

注意:在 simple_stmt 的末尾有一个换行符。if_stmt 不是 small_stmt;它不能在 ';' 后面跟着另一个 small_stmt。在 small_stmt 后面引入 compound_stmt 时,必须有一个换行符。

这不是问题,因为Bash允许多行参数。只要在完成之前不要关闭开头的单引号,例如:

python -c '
> import re
> if 1:
>   print(1)
> '

1

注意:这里的 > 是由命令行本身打印出来的,并不是手动输入的。

4

你可以直接在参数中插入换行符。

python -c 'import re
> if True:
>   print "HELLO"
> '
6

问题不在于 import 语句本身,而是你在控制流语句之前放了其他东西。这样做也是不行的:

dan@dan:~> python -c 'a = "1234" ; if True: print "hi"'
  File "<string>", line 1
    a = "1234" ; if True: print "hi"
                  ^
SyntaxError: invalid syntax

根据Python的官方文档(7. 复合语句),分号(';')只能用来把“简单语句”连接在一起。在这个例子中,你试图把简单语句 import reif True: 结合在一起。if True 不是简单语句,因为它引入了控制流,所以它是一个复合语句。至少我理解文档是这样的。

以下是Python官方文档的完整内容:

复合语句由一个或多个“子句”组成。一个子句包括一个头部和一个“语句块”。特定复合语句的所有子句头部都在同一缩进级别。每个子句头部以一个独特的关键字开始,并以冒号结束。语句块是由一个子句控制的一组语句。语句块可以是与头部在同一行的一个或多个用分号分隔的简单语句,紧跟在头部的冒号后面,或者可以是后续行中的一个或多个缩进语句。

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)* [";"]
13

解决这个限制的一个方法是使用 $'字符串' 这种格式来指定命令,并且在需要换行的地方使用 \n 来表示换行。

python -c $'import re\nif True: print "HELLO";'

注意:这种方法在一些命令行工具中是支持的,比如 BashZ shell(也叫 zsh),但在 POSIX 标准的 Bourne shellsh)中是不适用的。

正如 slaadvak 提到的,这里还有其他一些解决方法: 在一行命令行中执行 Python 多行语句

撰写回答