我认为这个问题已在某处得到解决,但我花了大量时间寻找答案,包括深入研究源代码。我试图把问题放在第一段。其余部分显示了问题的基本示例。
我正在尝试编译一个包含USE
语句的模块,该语句指向另一个更通用的模块。我更希望将使用过的模块保持独立,以便可以将它作为一组常规设置用于多个“包”中。当我使用f2py编译这两个模块时,一切都像fortran那样宣传,但是从python端USE
似乎被忽略了。如果我允许f2py生成签名文件,则该文件包含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
为了说明从fortran的角度在test2中正确定义b
,以下代码使用test2并打印b
和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之后,可以在python中导入run_test并按预期工作:
In [1]: import run_test
In [2]: run_test.run_test()
a = 1
b = 2
对此问题的任何帮助将不胜感激。
USE
的F90模块由f2py编译时,它不会将“used”模块中定义的参数公开为Python中的属性。 答案 0 :(得分:6)
我找到了解决此问题的临时解决方案,但这并不是最佳解决方案。我将继续使用f2py源代码,以便我能够更好地理解它并在代码本身内解决问题。在此之前,这是我的解决方案,其灵感来自chatcannon's comment to the issue I posted to nympy's github。
有几种方法可以从临时角度处理此问题,包括修改.pyf文件的几种方法。我不想修改.pyf文件,因为它变得非常麻烦,作为更大的包的一部分。为了避免这种情况,我在我的f90源代码中添加了f2py指令。
以我原来的问题为例:
MODULE test
INTEGER, PARAMETER :: a = 1
END MODULE test
MODULE test2
USE test
INTEGER, PARAMETER :: b = 2
END MODULE test2
只需在test2中添加一个f2py指令即可显示f2py如何定义test2.a
:
MODULE test
INTEGER, PARAMETER :: a = 1
END MODULE test
MODULE test2
USE test
!f2py integer, parameter :: a ! THIS EXPOSES `a` in `test2`
INTEGER, PARAMETER :: b = 2
END MODULE test2
从结果test.so
导入正确公开test2.a
:
In [1]: import test
In [2]: print test.test.a
1
In [3]: print test.test.b
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
.../test_solution/<ipython-input-3-798b14f59815> in <module>()
----> 1 print test.test.b
AttributeError: b
In [4]: print test.test2.a
1
In [5]: print test.test2.b
2