如何通过f2py实现Python与Fortran子程序的变量更新与传递
解决f2py中Fortran子程序与Python间标量变量更新问题
问题核心在于Python原生int是不可变对象:当你把Python的int类型变量b传递给Fortran子程序时,f2py仅能传递它的值副本,无法修改原变量本身;而NumPy数组是可变容器,内存布局与Fortran兼容,因此数组a的修改能同步到Python中。
下面是两种可行的解决方法:
方法一:用NumPy标量数组传递整数
将Python中的b替换为NumPy的0维数组(标量数组),让f2py可以直接修改其内存中的值:
修改后的Python脚本r.py:
import fortran_script import numpy as np a = np.array([10, 20, 30], np.float32) # 用numpy的int32类型标量数组替代原生int b = np.array(10, dtype=np.int32) fortran_script.fmodule.r(a, b) print(f"a = {a}") # 用item()取出数组中的标量值 print(f"b = {b.item()}")
重新编译运行后,Python就能输出正确的b = 20。
方法二:将Fortran子程序改为函数(可选)
如果不想修改Python代码,可以把Fortran子程序改成函数,让更新后的b作为返回值:
修改后的Fortran脚本r.f90:
module fmodule implicit none contains function r(a, b) result(new_b) real, intent(inout):: a(:) integer, intent(in) :: b integer :: new_b a(1:3)=a(3:1:-1) new_b = b + 10 write(*,*) 'a = ', a write(*,*) 'b = ', new_b end function r end module fmodule
对应的Python脚本:
import fortran_script import numpy as np a = np.array([10, 20, 30], np.float32) b = 10 # 接收函数返回的新b值 b = fortran_script.fmodule.r(a, b) print(f"a = {a}") print(f"b = {b}")
关键原理总结
- NumPy数组是可变容器,其内存布局与Fortran兼容,f2py可以直接修改数组内存中的数据,因此
a的修改能同步到Python。 - Python原生数值类型(
int、float)是不可变对象,传递给f2py时只会传递值的副本,Fortran修改的是副本而非原变量,所以原变量值不会改变。
内容的提问来源于stack exchange,提问作者Tanus Szabo
相关产品推荐
相关产品推荐

