我有一个代码工作流程,其中我从主脚本(级别 0)通过 subprocess
调用另一个脚本。此 subprocess 脚本
(级别 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`
当我执行上面的操作时,我在 print value
命令中得到了 UnboundLocalError: local variable 'value' referenced before assignment
。似乎如果我不执行 1 级脚本中的代码并执行 sys.exit() 那么主脚本中的 out
既不为空也不为空,但它有一些未定义的值,因此 value
变量未初始化并抛出错误
最佳答案
如果您只想返回一个整数值,您可以使用退出值。这与从 some_func()
返回不同,您必须执行 sys.exit(integer_val)
。
如果你想返回像 time
这样的字符串,你应该打印它(或写入 sys.stdout
),然后在调用过程中(级别 1)解析子进程的输出并将其打印到自己的标准输出以供 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()
来传递这些信息。如果被调用的进程具有非零退出状态(即出错),则会引发异常。我还可以建议,如果子进程写入的信息不仅仅是变量,您可以通过在行的开头返回一些独特的内容来使输出行易于解析(这样您仍然可以使用打印语句来调试各个脚本和 从输出中获取正确的值):
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()
一级:
...
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
以检查您可能损坏的内容。提交每个修订版,这样您就可以回滚到上一个“已知良好”状态,然后慢慢引入其余代码。
关于python - 从python中的子进程返回一个变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30982820/