如何在调用 python 脚本时捕获 python 脚本的结果? [复制]

Posted

技术标签:

【中文标题】如何在调用 python 脚本时捕获 python 脚本的结果? [复制]【英文标题】:How can I capture the result of a python script in calling python script? [duplicate] 【发布时间】:2015-06-02 22:52:10 【问题描述】:

python 新手。

我正在尝试从 python 脚本调用 python 脚本,除了捕获结果之外,我大部分都成功了。

a.py

status = subprocess.call("python /hosting/apps/b.py"+" "+server+" "+port+" "+sid, shell=True)

b.py 在第二个脚本中,我正在做一些计算并尝试使用 print 和 return 传回名为 status 的变量

print status;
return status;

这似乎不起作用。这是正确的做法吗?

【问题讨论】:

你需要使用子进程吗?为什么不使用 a.py 的import b? (docs.python.org/2/tutorial/modules.html) 使用 Popen 并读取进程的标准输出。此处的说明:***.com/questions/2502833/… 您应该导入 b 模块并调用适当的函数以直接获取结果(如果您需要多个线程,可以使用threadingmultiprocessing 等模块, processes) 而不是将b.py 作为外部进程运行并捕获其输出。 【参考方案1】:

cmets 中建议的两个选项可能是您最好的选择。以下是一些小的工作示例:

在这里,b.pystatus 设置为当前时间,并打印出来。

b.py

import time

status = time.time()

print status

a.py(子进程)

import subprocess

p = subprocess.Popen('python -u b.py', stdout=subprocess.PIPE)

(out,_) = p.communicate()

b_status = out

print b_status

输出:

1427685638.46

(注意,这里的额外空间是有意的,b_status 将有一个尾随换行符。这是要记住的事情。)

a.py(导入)

import b

b_status = b.status   # Directly access b.py's status variable

print b_status

输出:

1427685801.45 1427685801.45

注意status 使用第二种方法显示两次。一次在 b.py 的 print status 和一次在 a.py 的 print b_status。不要让它混淆你,b_status 只包含时间戳,而不像第一种方法那样包含尾随换行符。

(实际上,第一种方法也“显示”了两次,但是 b.py 的输出被 a.py 捕获,这是使用该方法时设置 b_status 的方式。)

总的来说,我认为导入是更好的选择,因为打印和解析它更容易出错。

【讨论】:

感谢 jedwards,我在下面尝试了没有运气p = subprocess.Popen('python -u b.py'+' '+server+' '+port+' '+sid, stdout=subprocess.PIPE) (out,_) = p.communicate() b_status = out print b_status f = open('/tmp/test_log.log','a') f.write('\n') f.write(b_status) f.close() 不确定这里有什么问题。但无法让它工作 你能给我们确切的错误信息吗? 如果我在您的回答中尝试上面提到的确切 popen 代码,我会收到以下错误 $ python a.py Traceback (most recent call last): File "a.py", line 3, in ? p = subprocess.Popen('python -u b.py', stdout=subprocess.PIPE) File "/usr/lib64/python2.4/subprocess.py", line 550, in __init__ errread, errwrite) File "/usr/lib64/python2.4/subprocess.py", line 996, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory Okie,os.popen 为我工作。但是我遇到了一个新问题。当我手动运行 a.py 时,一切正常......但在我的情况下,a.py 是从应用程序触发的。并且这个 os.popen 在这个过程中不起作用。 实际上,它需要子脚本的完整路径。而不是 a.py 它需要 /hosting/apps..../a.py【参考方案2】:

您可以使用subprocess.check_output() 而不是subprocess.call() 在变量中检索标准输出的内容(您在其中使用print 而不是return 如BBrown 所指出的那样编写)。这种方法非常通用,不限于 python 脚本(您可以调用任何可访问的可执行文件)。

status = subprocess.check_output("python /hosting/apps/b.py"+" "+server+" "+port+" "+sid, shell=True)

但是,您将检索输出作为您需要解析的字符串(在执行b.py 期间打印的所有内容)。您可能想要做的是在b.py 模块中定义一个函数:

## b.py
def main(server, port, sid):
  # Do things
  return status

并从a.py 调用它(前提是b 在你的sys.path 中):

## a.py
import b
status = b.main(server, port, sid)

【讨论】:

subprocess.check_output 对我不起作用。我的第二个脚本没有被执行。有什么建议吗? 我正在运行 python 2.4.3。 check_output 是否仅在更高版本中可用? 确实,根据文档,check_output2.7 版中的新功能。在这种情况下,您将需要使用@jedwards 提到的Popen。如果可能的话你应该升级,这个python版本已经快十年了。【参考方案3】:

return 不会从模块(即文件)返回值;这仅适用于使用 def 关键字创建的函数。您可以设置sys.stdout。见Redirect stdout to a file in Python?。

【讨论】:

以上是关于如何在调用 python 脚本时捕获 python 脚本的结果? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中捕获对对象调用的任何方法?

如何在网页中调用python脚本?

并行计算Python / Raspberry Pi

如何从 python 脚本成功调用 gsutil rsync?

如何使用调用 UDF 的 Python 脚本来使用 BigQuery API

如何在使用 oauthlib.oauth2 fetch_token 时捕获 API 失败