如何在调用 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
模块并调用适当的函数以直接获取结果(如果您需要多个线程,可以使用threading
、multiprocessing
等模块, processes) 而不是将b.py
作为外部进程运行并捕获其输出。
【参考方案1】:
cmets 中建议的两个选项可能是您最好的选择。以下是一些小的工作示例:
在这里,b.py
将 status
设置为当前时间,并打印出来。
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_output
是 2.7 版中的新功能。在这种情况下,您将需要使用@jedwards 提到的Popen
。如果可能的话你应该升级,这个python版本已经快十年了。【参考方案3】:
return 不会从模块(即文件)返回值;这仅适用于使用 def
关键字创建的函数。您可以设置sys.stdout
。见Redirect stdout to a file in Python?。
【讨论】:
以上是关于如何在调用 python 脚本时捕获 python 脚本的结果? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何从 python 脚本成功调用 gsutil rsync?