python - 如何将 C++ 函数的输出保存到 python 变量
问题描述
我已经在使用 boost 的 C++ 中的 python 脚本中具有工作功能。
这个函数正在打印我一些数据(字符串)要调用这个函数,我正在使用这个代码:
import cpp as cpp_fun #importing from c++ already compiled with boost (no exe)
file = path_to_file #doesn't matter which file
cpp_fun.strings(file)#gives me output
output:
"this is test string, one line of many.."
我什至不需要用来print(cpp_fun.strings())
打印输出,所以问题是,我不能将它添加到变量中,然后打印这个变量,因为当我运行 python 时,这个函数一直在打印输出。
我想将输出保存cpp_fun.strings()
到变量但是当我这样做时:
strings = cpp_fun.strings()
它再次给了我输出...
我尝试创建方法 ( def()
) 并将此函数放入其中,但毕竟结果相同,我也尝试捕获输出:
old_stdout = sys.stdout
new_stdout = StringIO()
sys.stdout = new_stdout
print(cp_fun.strings())
output = new_stdout.getvalue()
sys.stdout = old_stdout
但如果没有成功,上面的这个问题适用于正常打印,但不适用于这个。我也试过添加var=subprocess.check_output([cpp_fun])
- 不工作也许你有任何想法如何将它保存到变量?
解决方案
用一个普通的Python模块替换了你的cpp扩展模块,它只是打印它作为参数接收的文件的每一行。下面是捕获其输出的示例。
cpp.py:
def strings(file_name):
with open(file_name) as f:
for line in f:
print(line.rstrip())
代码00.py:
#!/usr/bin/env python
import sys
import io
import traceback
import cpp as cpp_fun
def capture_function_output(func, *func_args):
tmp_buf_out = io.StringIO()
tmp_buf_err = io.StringIO()
_sys_stdout = sys.stdout
sys.stdout = tmp_buf_out
_sys_stderr = sys.stderr
sys.stderr = tmp_buf_err
try:
func_ret = func(*func_args)
except:
func_ret = None
traceback.print_exc()
tmp_buf_out.flush()
tmp_buf_err.flush()
sys.stdout = _sys_stdout
sys.stderr = _sys_stderr
tmp_buf_out.seek(0)
func_stdout = tmp_buf_out.read()
tmp_buf_err.seek(0)
func_stderr = tmp_buf_err.read()
return func_ret, func_stdout, func_stderr
def test_capture_cpp_fun_output(file_name):
retcode, sout, serr = capture_function_output(cpp_fun.strings, file_name) # Store function return code, stdout and stderr contents into 3 variables
print("Function ({0:s}) returned: {1:}".format(cpp_fun.strings.__name__, retcode))
print("Function printed to stdout: \n{0:s}".format(sout))
print("--- Done")
print("Function printed to stderr: \n{0:s}".format(serr))
print("--- Done")
def main(*argv):
for file_name in [
"dummy.txt",
"dummy.txt0", # Doesn't exist!
]:
print("\nTesting file: {0:s}:".format(file_name))
test_capture_cpp_fun_output(file_name)
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
输出:
e:\Work\Dev\StackOverflow\q060851454>sopr.bat *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [prompt]> type dummy.txt dummy line 0 next line 0123456789 [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Testing file: dummy.txt: Function (strings) returned: None Function printed to stdout: dummy line 0 next line 0123456789 --- Done Function printed to stderr: --- Done Testing file: dummy.txt0: Function (strings) returned: None Function printed to stdout: --- Done Function printed to stderr: Traceback (most recent call last): File "code00.py", line 18, in capture_function_output func_ret = func(*func_args) File "e:\Work\Dev\StackOverflow\q060851454\cpp.py", line 2, in strings with open(file_name) as f: FileNotFoundError: [Errno 2] No such file or directory: 'dummy.txt0' --- Done Done.
更新#0
将代码更改为还捕获函数的stderr。
更新#1
添加[Python 3.Docs]: subprocess - 基于子流程管理的变体(在我这边也适用)。这需要一个额外的脚本(cpp_wrapper.py,它依赖于上面的cpp.py)。
cpp_wrapper.py:
import sys
import cpp as cpp_fun
if __name__ == "__main__":
if (len(sys.argv) < 2):
raise RuntimeError("Missing argument")
file_name = sys.argv[1]
try:
cpp_fun.strings(file_name)
except:
raise
else:
raise RuntimeError("This module should be executed directly")
代码01.py:
#!/usr/bin/env python
import sys
import subprocess
def capture_cpp_fun_output(file_name):
cmd = (sys.executable, "cpp_wrapper.py", file_name)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
return p.returncode, out.decode(), err.decode()
def main(*argv):
for file_name in [
"dummy.txt",
"dummy.txt0", # Doesn't exist!
]:
print("\nTesting file: {0:s}:".format(file_name))
retcode, sout, serr = capture_cpp_fun_output(file_name) # Store function return code, stdout and stderr contents into 3 variables
print("Function returned: {0:}".format(retcode))
print("Function printed to stdout: \n{0:s}".format(sout))
print("--- Done")
print("Function printed to stderr: \n{0:s}".format(serr))
print("--- Done")
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
输出:
[prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code01.py Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Testing file: dummy.txt: Function returned: 0 Function printed to stdout: dummy line 0 next line 0123456789 --- Done Function printed to stderr: --- Done Testing file: dummy.txt0: Function returned: 1 Function printed to stdout: --- Done Function printed to stderr: Traceback (most recent call last): File "cpp_wrapper.py", line 11, in <module> cpp_fun.strings(file_name) File "e:\Work\Dev\StackOverflow\q060851454\cpp.py", line 2, in strings with open(file_name) as f: FileNotFoundError: [Errno 2] No such file or directory: 'dummy.txt0' --- Done Done.
推荐阅读
- c# - Selenium 驱动程序在用作 lambda 函数的闭包时不起作用
- directory - 重启实例时云存储目录消失
- python - 在 pandas 中使用方程
- haskell - Haskell:知道变量的类型是否派生 Eq
- sql - 使用 Date_trunc 将日期转换为 PostgreSQL
- sql-server - 获取用户或应用程序查询的长时间运行查询
- npm - 如何为 BuckleScript / ReasonML 打包节点模块?
- python - lstm_5层的输入0与层不兼容:预期ndim=3,发现ndim=2
- r - R:将大矩阵转换为数据框格式,其中 1 行的值必须变为 1 列的不同行
- android-studio - 如何在android studio中使用之前版本的gradle?