我使用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语句。它是在for循环之前的任何东西。或者更具体地说,出现在内联块之前的任何东西。
例如,这些都是有效的:
python -c "import sys; print 'rob'"
python -c "import sys; sys.stdout.write('rob\n')"
如果import是一个语句是一个问题,这将工作,但它不是:
python -c "__import__('sys'); for r in range(10): print 'rob'"
对于最基本的例子,你可以这样写:
python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"
然而,lambdas只能执行表达式,而不能执行语句或多条语句,因此您可能仍然无法执行您想要执行的事情。然而,在生成器表达式、列表理解、lambdas、sys.stdout之间。写,“映射”内置,和一些创造性的字符串插值,你可以做一些强大的一行程序。
问题是,您想要走多远,以及在什么情况下编写一个小的.py文件而让makefile执行不是更好?
这种风格也可以在makefile中使用(事实上它经常被使用)。
python - <<EOF
import random
for r in range(3): print(random.randint(1, 42))
EOF
或者用硬标签:
python - <<-EOF
import random
for r in range(3): print(random.randint(1, 42))
EOF
# Important: Replace the indentation above w/ hard tabs.
在上述情况下,前导制表符也被删除(并且可以实现一些结构化的外观)。
EOF可以容忍没有出现在这里文档中的任何标记词,出现在一行的开头(另请参阅bash手册页中的文档或这里的文档)。
这个变体在Windows和类unix系统(Python 2和Python 3)的命令行上放置多行脚本是最可移植的,没有管道:
python -c "exec(\"import sys \nfor r in range(10): print('rob') \")"
(到目前为止,这里看到的其他例子都没有这样做。)
Windows上的Neat是:
python -c exec"""import sys \nfor r in range(10): print 'rob' """
python -c exec("""import sys \nfor r in range(10): print('rob') """)
类unix系统上Bash的Neat是:
python -c $'import sys \nfor r in range(10): print("rob")'
该函数将任何多行脚本转换为可移植的命令行:
def py2cmdline(script):
exs = 'exec(%r)' % re.sub('\r\n|\r', '\n', script.rstrip())
print('python -c "%s"' % exs.replace('"', r'\"'))
用法:
>>> py2cmdline(getcliptext())
python -c "exec('print \'AA\tA\'\ntry:\n for i in 1, 2, 3:\n print i / 0\nexcept:\n print \"\"\"longer\nmessage\"\"\"')"
输入是:
print 'AA A'
try:
for i in 1, 2, 3:
print i / 0
except:
print """longer
message"""