Python timeit命令行错误:";SyntaxError:EOL在扫描字符串文字时;
我已经使用Python模块很长时间了,但它只是通过交互式Python会话或Unix shell实现的。现在,我试图测量Windows命令提示符(cmd.exe)中的一些代码片段,但它显示了以下错误:Python timeit命令行错误:";SyntaxError:EOL在扫描字符串文字时;,python,windows,command-line,cmd,timeit,Python,Windows,Command Line,Cmd,Timeit,我已经使用Python模块很长时间了,但它只是通过交互式Python会话或Unix shell实现的。现在,我试图测量Windows命令提示符(cmd.exe)中的一些代码片段,但它显示了以下错误: C:\Users\Me>python -m timeit '"-".join(map(str, range(100)))' Traceback (most recent call last): File "C:\Python33\lib\runpy.py", line 160, in _r
C:\Users\Me>python -m timeit '"-".join(map(str, range(100)))'
Traceback (most recent call last):
File "C:\Python33\lib\runpy.py", line 160, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "C:\Python33\lib\runpy.py", line 73, in _run_code
exec(code, run_globals)
File "C:\Python33\lib\timeit.py", line 334, in <module>
sys.exit(main())
File "C:\Python33\lib\timeit.py", line 298, in main
t = Timer(stmt, setup, timer)
File "C:\Python33\lib\timeit.py", line 131, in __init__
code = compile(src, dummy_src_name, "exec")
File "<timeit-src>", line 6
'-.join(map(str,
^
SyntaxError: EOL while scanning string literal
我确信我正确地调用了该模块,因为我已经在Unix shell上粘贴了相同的行,它们按照预期工作
由于我在Python2.7和3.3中得到了完全相同的结果(另外,该模块是用纯Python编写的,并且已经存在很长时间了),因此我确信这与Python无关,而与Windows命令提示符无关
那么,为什么会发生这种奇怪的行为,我该如何解决它呢?tl;博士
对传递给timeit模块的语句使用双引号。例如: 详细说明 与bash和tcsh等unixshell不同,单引号在Windows命令行上的处理方式有所不同 下面是一个小型python程序来演示这一点:
import sys
print(sys.argv[1:])
运行此命令(让我们调用文件cmdtest.py),我们可以观察到以下情况:
C:\Users\Me\Desktop>python cmdtest.py 1 2 3
['1', '2', '3']
C:\Users\Me\Desktop>python cmdtest.py "1 2 3"
['1 2 3']
C:\Users\Me\Desktop>python cmdtest.py '1 2 3'
["'1", '2', "3'"]
因此,单引号按字面意思处理(即不作为特殊字符)。搜索了一下,我发现:
从命令窗口调用命令时,将
命令行参数不是由cmd.exe
(又称“shell”)完成的。
标记化通常由新形成的进程的
C/C++运行时,但不一定如此——例如,如果
新进程不是用C/C++编写的,或者如果新进程选择
忽略argv
并自行处理原始命令行(例如,使用
[GetCommandLine()][1])。在操作系统级别,Windows传递命令行
未作为单个字符串指定给新进程。这是相反的
对于大多数*nix shell,shell在
在将其传递给新组建的团队之前,以一致、可预测的方式
过程所有这些都意味着你可能会经历巨大的分歧
Windows上不同程序的参数标记化行为,
由于各个程序通常将参数标记化纳入自己的程序中
手
如果这听起来像是无政府状态,那就有点像。然而,由于
许多Windows程序使用Microsoft C/C++运行时的
argv
,了解MSVCRT
标记化参数。以下是摘录:
- 参数由空格分隔,空格可以是空格,也可以是制表符
- 被双引号包围的字符串被解释为单个参数,而不管其中包含的空格。引用的 字符串可以嵌入到参数中。请注意,插入符号(^)不是 被识别为转义字符或分隔符
错误#2 考虑到上述情况,让我们首先解释第二种奇怪的行为(充当
pass
语句的行为),因为它稍微简单一些。由于单引号是按字面解释的,因此调用时:
C:\Users\Me>python -m timeit 'map(str,range(100))'
C:\Users\Me>python -m timeit '"-".join(map(str, range(100)))'
确切的字符串literal“map(str,range(100))”
(包括引号)作为语句传递给time。因此,Python将看到
"'map(str,range(100))'"
而不是
'map(str,range(100))'
作为一个字符串,它实际上不起任何作用,并且给出的度量非常接近于pass
语句
错误#1 现在来看第一个错误:
正如python模块的文档所述: 多行语句可以通过将每一行指定为 独立陈述论点 因此,打电话时:
C:\Users\Me>python -m timeit 'map(str,range(100))'
C:\Users\Me>python -m timeit '"-".join(map(str, range(100)))'
Python将[“'-.join(map(str),“range(100)))”]
作为语句传递给timeit,模块将其解释为多行语句:
'"-".join(map(str,
range(100)))'
PS C:\Users\Me> python -m timeit 'map(str, range(100))'
1000000 loops, best of 3: 0.688 usec per loop
这有一个字符串作为它的第一行,该字符串以单引号打开,但从不关闭,因此,(最终)解释了奇怪的EOL错误
解决方案 对语句使用双引号来计时可以解决这个问题 我还尝试过Windows PowerShell,它比cmd.exe更高级,并且在Unix shell中表现出类似的行为,但在我测试的所有语句中都没有做到这一点。
例如,这是有效的(注意语句中的空格): 虽然最初的示例没有:
PS C:\Users\Me\Desktop> python -m timeit '"-".join(map(str, range(100)))'
option -. not recognized
use -h/--help for command line help
(不过,我还不是很满意。我更愿意做的是让cmd或PowerShell作为Unix shell工作,这样我就可以简单地粘贴和计时代码片段。如果有人知道一种快速而肮脏的方法(如果可能的话),为了完成答案,那就太棒了。)