我有一个代码工作流,从主脚本(级别0)我通过subprocess
调用另一个脚本。此subprocess script
(级别1)又将另一个脚本调用为subprocess
。现在从这个2级子进程脚本我想要将变量的值返回到主脚本(级别0)。我试过Popen.communicate()
,但我无法返回值。我目前的代码如下:
main_script.py
def func():
para = ['a','b']
result = subprocess.Popen([sys.executable,"first_subprocess.py"]+para,stdout=subprocess.PIPE)
result.wait()
return_code = result.returncode
out, err = sub_result.communicate()
if return_code == 1:
return return_code
else:
if out is not None:
print 'return value: ', out
if __name__ == '__main__':
func()
从上面的脚本称为first_subprocess.py
,其中包含:
def some_func():
# some other code and multiple print statements
para = ['a','b']
result = subprocess.Popen([sys.executable,"second_subprocess.py"]+para,stdout=subprocess.PIPE)
result.wait()
out, err = result.communicate()
return_code = sub_result.returncode
if return_code == 0:
return out
if __name__ == '__main__':
some_func()
second_subprocess.py
返回如下值:
def test():
# some other code and multiple print statements
val = 'time'
print 'returning value'
return val
if __name__ == '__main__':
test()
当我尝试上面的代码时,我将代码中的所有print
语句作为输出而不是返回值。即使尝试print
子进程中的变量值而不是返回它也不会达到目的,因为有多个print语句。
在这种情况下如何返回变量值?
更新版本:
在@Anthons建议之后,我修改了我的first_subprocess.py
脚本和main_script.py
,如下所示:
first_subprocess.py:
def some_func():
try:
key = None
if not (key is None):
para = ['a','b']
result = subprocess.Popen([sys.executable,"second_subprocess.py"]+para,stdout=subprocess.PIPE)
sub_result.wait()
out, err = sub_result.communicate()
return_code = sub_result.returncode
if return_code == 0:
for line in out.splitlines():
if not line.startswith('>>>'):
continue
print line
else:
sys.exit(0)
except:
return 1
Main_script.py:
if out is not None:
for line in out.splitlines():
if not line.startswith('>>>'):
continue
value = line.split(':',1)[1].lstrip()
print 'return value:',value`
当我在上面执行时,我在UnboundLocalError: local variable 'value' referenced before assignment
命令获得print value
。看来如果我不执行第1级脚本中的代码并执行sys.exit(),那么主脚本中的out
既不是空的也不是空的,但它有一些未定义的值,因此value
变量没有初始化并抛出错误
答案 0 :(得分:1)
如果您只想返回一个整数值,可以使用退出值。这与从some_func()
返回的情况不同,您必须执行sys.exit(integer_val)
。
如果要返回类似time
的字符串,则应打印该字符串(或写入sys.stdout
),然后在调用进程(级别1)中解析子进程的输出并将其打印到它自己的stdout为0级才能看到它。
在你的情况下,二级应该做类似的事情:
def test():
# some other code and multiple print statements
val = 'time'
print 'returning value:', val
if __name__ == '__main__':
test()
在第1级你会这样做:
def some_func():
# some other code and multiple print statements
para = ['a','b']
result = subprocess.Popen([sys.executable,"second_subprocess.py"]+para,stdout=subprocess.PIPE)
result.wait()
out, err = result.communicate()
return_code = sub_result.returncode
if return_code == 0:
print out
if __name__ == '__main__':
some_func()
使用main_script.py可以从调用1级脚本中读取内容。
我通常使用subprocess.check_output()
来传递这些信息。如果被调用进程具有非零退出状态(即出错时),则抛出异常。我还建议,如果子进程写入的信息多于变量,则可以通过在行的开头返回唯一的东西来使输出行易于解析(因此您仍然可以使用print语句来调试单个脚本和从输出中获取正确的值):
等级2:
def test():
# some other code and multiple print statements
print 'debug: Still going strong'
val = 'time'
print '>>>> returning value:', val
if __name__ == '__main__':
test()
等级1:
...
out, err = result.communicate()
for line in out.splitlines():
if not line.startswith('>>>>'):
continue
print line
...
等级0:
...
out, err = result.communicate()
for line in out.splitlines():
if not line.startswith('>>>>'):
continue
try:
value = line.split(':', 1)[1]
except IndexError:
print 'wrong input line', repr(line)
print 'return value: ', value
...
以下文件一起使用。将它们保存在指定的名称下
<强> lvl2.py 强>:
# lvl2
import sys
def test():
# some other code and multiple print statements
print >> sys.stderr, 'argv', sys.argv[1:]
print 'debug: Still going strong'
val = 'time'
print '>>>> returning value:', val
return 0
if __name__ == '__main__':
sys.exit(test())
<强> lvl1.py 强>:
# lvl1.py
import sys
import subprocess
def some_func():
para = ['a','b']
sub_result = subprocess.Popen(
[sys.executable, "lvl2.py" ] + para,
stdout=subprocess.PIPE)
sub_result.wait()
out, err = sub_result.communicate()
return_code = sub_result.returncode
if return_code == 0:
for line in out.splitlines():
if not line.startswith('>>>'):
continue
print line
else:
print >> sys.stderr, 'level 2 exited with' + return_code
sys.exit(0)
if __name__ == '__main__':
sys.exit(some_func())
<强> lvl0.py 强>:
# lvl0
import subprocess
import sys
def func():
para = ['a','b']
result = subprocess.Popen(
[sys.executable, "lvl1.py"] + para,
stdout=subprocess.PIPE)
result.wait()
return_code = result.returncode
out, err = result.communicate()
value = None
if return_code == 0:
for line in out.splitlines():
if not line.startswith('>>>'):
continue
value = line.split(':',1)[1].lstrip()
print
else:
print 'non-zero exit', return_code
print 'return value:', value
if __name__ == '__main__':
func()
然后运行python lvl0.py
以检查输出是否为
argv ['a', 'b']
return value: time
现在将这些内容放在您的修订控制系统下,并开始一次更改几行,每次都运行python lvl0.py
以检查您可能已经损坏的内容。提交每个修订版本,以便您可以回滚到最后一个“已知良好”状态并慢慢引入其余代码。