为什么导入subprocess会改变我的输出?

12

我用Python 2.5.2发现了以下问题(在2.7中没有出现):

#!/usr/bin/python

import sys

for line in sys.stdin:
   print line,

输出:

$ echo -e "one\ntwo\nthree" | python test.py
$ one
$ two
$ three

如预期所料。但是,如果我将subprocess导入到此脚本中:

#!/usr/bin/python

import sys
import subprocess

for line in sys.stdin:
   print line,

输出:

$ echo -e "one\ntwo\nthree" | python test.py
$ two
$ three

第一行输出怎么了?

更新:

我认为我可能已经找到了问题的根源。 我的cwd中有一个名为time.py的文件。 每次使用导入subprocess运行脚本时,都会创建一个time.pyc,表明./time.py也被导入了。 如果我删除.pyctime.py文件,脚本就可以正常运行; 但是,仍然有一个问题,即为什么subprocess导入会导致./time.py也被导入?

我进一步缩小了范围,找到了导致奇怪行为的time.py中精确的一行。 我将工作目录和文件内容剥离到只影响输出的部分:

test.py

#!/usr/bin/python

import sys
import subprocess

for line in sys.stdin:
   print line,

time.py

#!/usr/bin/python

import sys

for line in sys.stdin:
   hour = re.search(r'\b([0-9]{2}):', line).group(1)

使用任何输入运行test.py都会导致第一行输出被省略,并创建time.pyc


我无法在2.4.3上确认:执行命令“echo -e "one\ntwo\nthree" | python test.py”会导致最后一个示例输出“-e one two three”。 - tb-
1
@tb-:你必须使用bash shell。echo是一个内置命令,而tcsh(例如)不支持-e标志。 - Bill Lynch
1
@SilentGhost:我在Debian 5.0.6上使用2.5.2得到了这些结果。同一台机器上的Python 2.6.6和2.7.1表现如预期。 - alh
我已经尝试过使用Python2.6和2.7,所有行都能正确输出,就像你期望的那样。虽然这并没有什么用,但也许你还缺少其他东西。 - Samuele Mattiuzzo
你的 time.py 文件在运行时有输入吗?如果是这样,它可能会消耗你的 "one" 行。通常情况下,出于这个原因,用与标准库中某些东西相同的名称命名自己的模块不是一个好主意! 包可以有所帮助。 - Blckknght
显示剩余5条评论
2个回答

1

看起来你的 local time.py 模块将会被导入而不是全局的 time 模块。你可能想要重命名它,或者至少开始检查它是否作为脚本运行或作为模块导入。

如果你想测试一下,这将为你证明它。

#!/usr/bin/python

import sys

# Test that script was run directly
if __name__=='__main__':
    for line in sys.stdin:
       hour = re.search(r'\b([0-9]{2}):', line).group(1)
else:
    print 'Imported local time.py instead of global time module!'
    sys.exit(1)

-2

print line, 在2.7版本之前没有输出换行符,因此它会覆盖第一行。去掉逗号,结果将是相同的。


2
为什么第二行 two\n 没有被覆盖?另外,import subprocess 不应该对它产生影响。 - SilentGhost
在2.7中,尾随逗号的行为没有改变。 - Ned Batchelder
print中的尾随逗号的目的是省略换行符,详情请参考http://docs.python.org/2/reference/simple_stmts.html#grammar-token-print_stmt "除非print语句以逗号结尾,否则会在末尾写入一个'\n'字符"。 - dbr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接