我想创建一个文件,用作python脚本的标准输入,并使用subprocess.call调用所述脚本。
当我在命令行中直接执行它时,它可以正常工作:
输入文件:
# test_input
1/2/3
python脚本
# script.py
thisDate = input('Please enter date: ').rstrip()
以下命令可以正常工作:
python script.py < test_input
但是当我尝试在另一个python脚本中执行以下操作时,它不起作用。 (来自this)
outfile1 = open('test_input', 'w')
outfile1.write('1/2/3')
outfile1.close()
input1 = open('test_input')
subprocess.call(['python', 'script.py'], stdin=input1)
但后来我收到以下错误:
>>>thisDate = input('Please enter date: ').rstrip()
>>>AttributeError: 'int' object has no attribute 'rstrip'
当我进行一些调试时,它似乎是将整数0作为输入。
造成这种不一致的原因是什么?这两种方法不相同(显然它们不是,但为什么)?我的最终目标是执行与上述命令行版本完全相同的任务。
谢谢
答案 0 :(得分:1)
您正在使用input
,raw_input
时,{python2中的input
会eval
字符串。如果您使用python3
运行脚本,它将按原样运行,python2
更改为raw_input
。
使用check_call
通常是一种更好的方法,并使用with
打开您的文件。
import subprocess
with open('test_input') as input1:
subprocess.check_call(['python3', 'script.py'], stdin=input1)
答案 1 :(得分:0)
所以chepner是正确的。当我修改以下行时:
subprocess.call(['python', 'script.py'], stdin=input1)
为:
subprocess.call(['python3', 'script.py'], stdin=input1)
它运作得很好。
(我试图在python3中这样做)
答案 2 :(得分:0)
在第一个实例中,文件有两行,input()
读取并解析第一行,这是一个注释。
在第二种情况下,缺少注释行,因此Python会读取并解析一个数字。
您可能打算使用raw_input()
,或者使用Python 3运行脚本。
(您可能还意味着输入文件以换行符结束,当您运行Python时,使用subprocess.call()
运行Python并没有多大意义。)
答案 3 :(得分:0)
python script.py < test_input
命令应该失败。您可能需要:python3 script.py < test_input
,而不是由于其他答案中提到的Python 2上input()
与raw_input()
之间的差异。 python
as a rule指的是Python 2版本。
如果仅使用python3
运行父脚本,则可以使用sys.executable
使用相同的python
版本运行子脚本(相同的可执行文件) ):
#!/usr/bin/env python3
import subprocess
import sys
with open('test_input', 'rb', 0) as input_file:
subprocess.check_call([sys.executable or 'python3', 'script.py'],
stdin=input_file)
如果父母和孩子可以使用不同的python版本,那么在script.py
中设置正确的shebang,例如#!/usr/bin/env python3
并直接运行脚本:
#!/usr/bin/env python
import subprocess
with open('test_input', 'rb', 0) as input_file:
subprocess.check_call(['./script.py'], stdin=input_file)
这里,子脚本可以选择自己的python版本。确保脚本具有可执行权限:chmod +x script.py
。注意:Python Launcher for Windows也理解shebang语法。
无关:使用.communicate()
代替outfile1.write('1/2/3')
:
#!/usr/bin/env python3
from subprocess import Popen, PIPE
with Popen(['./script.py'], stdin=PIPE, universal_newlines=True) as p:
p.communicate('1/2/3')