我认为这个问题已经在某个地方得到解决,但我花了大量的时间四处寻找答案,包括深入研究源代码。我试图将问题放在第一段中。其余部分显示了问题的基本示例。
我正在尝试编译一个包含USE
指向另一个更通用的模块的语句。我更愿意将使用的模块分开,以便它可以作为一组常规设置在多个“包”中使用。当我使用 f2py 编译这两个模块时,一切都按照 fortran 端所宣传的那样工作,但从 python 端来看USE
似乎被忽略了。如果我允许 f2py 生成签名文件,该文件包含USE
声明是适当的,但是如果我完成编译并从生成的库导入,则所使用模块中的参数在包含 use 语句的模块中不可用。下面是说明这种情况的两个模块:
MODULE test
INTEGER, PARAMETER :: a = 1
END MODULE test
MODULE test2
USE test
INTEGER, PARAMETER :: b = 2
END MODULE test2
为了展示我跑的中间步骤f2py -h test.pyf test.f90 test2.f90
。生成如下签名文件;请注意,“test2”模块包含“use test”:
! -*- f90 -*-
! Note: the context of this file is case sensitive.
python module test ! in
interface ! in :test
module test ! in :test:test.f90
integer, parameter,optional :: a=1
end module test
module test2 ! in :test:test2.f90
use test
integer, parameter,optional :: b=2
end module test2
end interface
end python module test
! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/
如果我现在编译f2py --fcompiler=gfortran -c test.pyf test.f90 test2.f90
我获得 test.so (与运行相同f2py --fcompiler=gfortran -m test -c test.f90 test2.f90
无需先创建签名文件)。在 python 中从该库导入会公开 test.test.a 和 test.test2.b,但不会公开 test.test2.a,如下所示:
In [1]: import test
In [2]: print test.test.a
1
In [3]: print test.test2.b
2
In [4]: print test.test2.a
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/users/solbrig/svn_checkouts/inversion/satmet/branches/solbrig/rootpath/data/users
/GeoIPS/src/test/<ipython-input-4-bffcf464e408> in <module>()
----> 1 print test.test2.a
AttributeError: a
只是为了说明这一点b
从 fortran 的角度来看,test2 中定义正确,以下代码使用 test2 并打印两者b
and b
:
SUBROUTINE run_test()
USE test2
IMPLICIT NONE
print *, "a = ", a
print *, "b = ", b
END SUBROUTINE run_test
使用“f2py -m run_test -c test.f90 test2.f90 run_test.f90”编译并获得run_test.so后,run_test可以在python中导入并按预期工作:
In [1]: import run_test
In [2]: run_test.run_test()
a = 1
b = 2
任何有关此问题的帮助将不胜感激。
TL;DR:当 F90 模块包含USE
由 f2py 编译,它不会将“used”模块中定义的参数公开为 Python 中的属性。