f2py编译F77程序时如何暴露非公共块变量供Python访问
问题根因
f2py编译Fortran代码生成Python模块时,默认仅导出两类可访问实体:
- 对外可见的
SUBROUTINE子例程、FUNCTION函数,及其形参、返回值 COMMON公共块定义的全局变量
你当前代码写的是PROGRAM主程序单元,f2py不会将主程序作为可调用入口执行,主程序内部定义的XINT、X、Y、W、IFILE、TITLE都属于主程序的局部变量,既不会被初始化,也不会暴露到Python模块接口中,因此你只能看到已定义的COMMON块hlm,无法访问局部数组。
正确改造方式
根据遗留代码的改造难度,二选一即可:
方案1:将需访问的变量移入COMMON公共块(改动最小,适配老代码优先选)
- 把原有
PROGRAM主程序改写为无参数的初始化子例程,否则主程序逻辑不会被执行,公共块内存会是未初始化的随机值 - 把需要在Python侧访问的局部变量,新增到已有COMMON块或单独新建COMMON块存放
改造后的代码示例:
SUBROUTINE TEST_INIT() IMPLICIT REAL*8(A-H,O-Z) CHARACTER IFILE*30, TITLE(8)*10 DIMENSION XINT(100), X(200), Y(200), W(200) COMMON /HLM/ DUMMX(2000) COMMON /SMY/ DUMMY(2130) COMMON /BLK1/ PI,PI2,RAD,CONS * 新建公共块存放需暴露的变量 COMMON /MYVAR/ XINT, X, Y, W COMMON /MYVAR_STR/ IFILE, TITLE * 原有主程序的初始化、计算逻辑放在这里 RETURN END
使用原命令f2py -c test.f -m test编译完成后,Python侧调用方式如下:
import test # 先调用子例程完成变量初始化 test.test_init() # 访问公共块中的数组 print(test.myvar.xint) print(test.myvar.x)
方案2:将需暴露变量定义为子例程形参
如果不需要这些变量作为全局公共变量存在,可以把主程序逻辑封装为子例程,将需要Python侧读写的变量全部列入形参表,f2py会自动生成参数传递接口,支持直接传入numpy数组交互:
SUBROUTINE TEST_CALC(XINT, X, Y, W, PI, PI2, RAD, CONS) IMPLICIT REAL*8(A-H,O-Z) * 所有需交互的变量作为形参声明 DIMENSION XINT(100), X(200), Y(200), W(200) CHARACTER IFILE*30, TITLE(8)*10 * 原有计算逻辑写在这里 RETURN END
注意事项
- F77固定格式代码需严格遵守语法规则:前6列为注释/行号/续行符位置,代码从第7列开始书写,否则f2py解析会报错
- 放在COMMON块中的字符型变量,f2py会自动映射为Python侧的bytes类型,使用时注意编码转换
- 不要尝试直接编译带PROGRAM主程序的F77代码实现变量访问,主程序逻辑在f2py生成的模块中永远不会自动执行
内容的提问来源于stack exchange,提问作者XYZ
相关产品推荐
相关产品推荐

