Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python timeit命令行错误:";SyntaxError:EOL在扫描字符串文字时;_Python_Windows_Command Line_Cmd_Timeit - Fatal编程技术网

Python timeit命令行错误:";SyntaxError:EOL在扫描字符串文字时;

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

我已经使用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 _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工作,这样我就可以简单地粘贴和计时代码片段。如果有人知道一种快速而肮脏的方法(如果可能的话),为了完成答案,那就太棒了。)