Fortran通过system()调用Python无法传递返回值的问题咨询
Fortran调用Python获取返回值问题解答
错误原因说明
system()函数的返回值是被调用进程的退出状态码,而非进程产生的业务数据:返回0代表Python脚本正常运行结束,非0代表脚本执行出错。该返回值和你Python代码中generate_a_number返回的数值完全无关。
同时你的Python代码仅在函数内返回了数值,没有将结果输出到外部,两个进程的内存空间完全隔离,Fortran无法直接读取Python进程内存中的数据。
结论:system()不能直接用于跨语言业务数据传递,仅可用于判断被调用程序是否正常运行。
可行的实现方案
方案1:捕获Python标准输出(适合小数据、简单调用场景)
这是最轻量化的实现方式,修改Python代码将结果打印到标准输出,再在Fortran中捕获输出内容转换为对应类型即可。
- 修改后的
python_number.py:
def generate_a_number(a): return a # 将结果打印到标准输出 print(generate_a_number(2))
- 修改后的Fortran代码(使用Fortran2008标准的
execute_command_line捕获输出):
program SystemTest character(len=256) :: output_buf integer :: py_num, run_stat print *, "FORTRAN: BLOCKING" ! 执行Python命令并捕获输出 call execute_command_line("python python_number.py", exitstat=run_stat, output=output_buf) if (run_stat == 0) then ! 将字符串类型的输出转换为整数 read(output_buf, *) py_num print *, "从Python获取的数值:", py_num else print *, "Python脚本执行失败,错误码:", run_stat end if print *, "FORTRAN: EXIT" end program SystemTest
如果使用的编译器不支持Fortran2008标准,也可以通过管道读取输出:
open(unit=20, file='python python_number.py |', status='old') read(20, *) py_num close(20)
方案2:中间文件传递(适合大数据、复杂结构场景)
如果需要传递大量数据、数组或者自定义结构,可以让Python将结果写入临时文件(txt/csv/二进制文件均可),Fortran执行完Python脚本后读取该文件获取数据。
- 修改后的Python代码:
def generate_a_number(a): return a res = generate_a_number(2) with open("tmp_result.txt", "w") as f: f.write(str(res))
- Fortran代码逻辑:
program SystemTest integer :: py_num, run_stat print *, "FORTRAN: BLOCKING" run_stat = system("python python_number.py") if (run_stat == 0) then open(unit=20, file="tmp_result.txt", status="old") read(20, *) py_num close(20) print *, "从Python获取的数值:", py_num end if print *, "FORTRAN: EXIT" end program SystemTest
方案3:原生接口互操作(适合高频调用、高性能要求场景)
如果需要频繁在Fortran和Python之间传递数据,可以使用F2PY工具将Python代码封装为Fortran可直接调用的动态库,或者使用CFFI实现C层的互操作,避免反复启动进程和IO开销,性能更高但实现复杂度也更高。
内容的提问来源于stack exchange,提问作者Junying Gao
相关产品推荐
相关产品推荐

