我使用Python和-c来执行一行循环,即:

python -c "for r in range(10): print 'rob'"

这很好。但是,如果我在for循环之前导入一个模块,就会得到一个语法错误:

python -c "import sys; for r in range(10): print 'rob'"

  File "<string>", line 1
    import sys; for r in range(10): print 'rob'
              ^
SyntaxError: invalid syntax

如何解决这个问题?

对我来说,将它作为一行程序很重要,这样我就可以将它包含在Makefile中。


当前回答

问题不在于import语句。问题是控制流语句不能内联在Python解释器命令中工作。将该import语句替换为任何其他语句,您将看到相同的问题。

想想看:Python不可能内联所有东西。它使用缩进来分组控制流。

其他回答

问题不在于import语句。问题是控制流语句不能内联在Python解释器命令中工作。将该import语句替换为任何其他语句,您将看到相同的问题。

想想看:Python不可能内联所有东西。它使用缩进来分组控制流。

python2.6 -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

工作很好。

使用“[]”内联for循环。

你知道怎么解决吗?

你的问题是由这样一个事实造成的:Python语句,用;分隔,只允许是“小语句”,它们都是一行程序。来自Python文档中的语法文件:

标准时间: simple_stmt |compound_stmt simple_stmt: small_stmt (“;”small_stmt)* [“;”]换行符 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt |global_stmt |nonlocal_stmt |assert_stmt)

复合语句不能通过分号与其他语句包含在同一行中——因此使用-c标志来做到这一点非常不方便。

在bash shell环境中演示Python时,我发现包含复合语句非常有用。唯一可靠的简单方法是使用heredocs (posix shell的东西)。

赫里多克斯

使用heredoc(使用<<创建)和Python的命令行接口选项,-:

$ python - <<-"EOF"
        import sys                    # 1 tab indent
        for r in range(10):           # 1 tab indent
            print('rob')              # 1 tab indent and 4 spaces
EOF

在<<之后添加-(<<-)允许您使用制表符缩进(Stackoverflow将制表符转换为空格,因此我缩进了8个空格以强调这一点)。前面的制表符将被剥离。

你可以在没有标签的情况下使用<<:

$ python - << "EOF"
import sys
for r in range(10):
    print('rob')
EOF

在EOF周围加上引号可以防止参数和算术扩展。这使得heredoc更加健壮。

Bash多行字符串

如果你使用双引号,你会得到shell- expand:

$ python -c "
> import sys
> for p in '$PATH'.split(':'):
>     print(p)
> "
/usr/sbin
/usr/bin
/sbin
/bin
...

为了避免shell扩展,请使用单引号:

$ python -c '
> import sys
> for p in "$PATH".split(":"):
>     print(p)
> '
$PATH

注意,我们需要在Python中对字面量交换引号字符-我们基本上不能使用由BASH解释的引号字符。我们可以交替使用它们,就像在Python中一样——但这看起来已经很混乱了,这就是为什么我不建议这样做:

$ python -c '
import sys
for p in "'"$PATH"'".split(":"):
    print(p)
'
/usr/sbin
/usr/bin
/sbin
/bin
...

对已接受答案(和其他答案)的批评

这不是很好读:

Echo -e "import sys\nfor rin range(10): print 'rob'" | python

可读性不强,而且在出现错误的情况下很难调试:

Python -c "exec(\"import sys\\nfor rin range(10): print 'rob'\")"

也许可读性更强一些,但仍然很难看:

(echo "import sys";Echo "for rin range(10): print 'rob'") | python

如果你的python里有",你就会过得很糟糕:

$ python -c "import sys . > for rin range(10): print 'rob'"

不要滥用map或list推导式来获取for循环:

import sys;Map (lambda x: sys.stdout。Write ('rob%d\n' % x), range(10))"

这些都是悲伤而糟糕的。不要这样做。

你可以这样做

echo -e "import sys\nfor r in range(10): print 'rob'" | python

或没有管道:

python -c "exec(\"import sys\nfor r in range(10): print 'rob'\")"

Or

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

或者沉默鬼的回答,或者卡斯特的回答。

我想要一个具有以下属性的解决方案:

可读的 读取标准输入以处理其他工具的输出

这两个要求在其他答案中都没有提供,所以下面是如何在命令行上执行所有操作时读取标准输入:

grep special_string -r | sort | python3 <(cat <<EOF
import sys
for line in sys.stdin:
    tokens = line.split()
    if len(tokens) == 4:
        print("%-45s %7.3f    %s    %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
EOF
)