Skip to main content
 首页 » 编程设计

python之f2py:模块中常量的奇怪行为

2025年05月04日13arxive

在 Fortran 模块中使用全局常量时,我​​发现 f2py 有一些奇怪的行为。

假设我有一个文件 test.f90,它看起来像

module test1 
  real, parameter :: a = 12345. 
end module test1 
 
module test2 
  real*8, parameter :: a = 6789. 
end module test2 

如果我用 f2py 包装它,使用

f2py -c -m mymod test.f90 

正在运行

python -c "import mymod as m; print m.test1.a; print m.test2.a" 

我明白了

12345.0 
6789.0 

这几乎是您所期望的。 real 和 real*8 语句的行为方式相同。

对于我的实际项目,我需要使用编译器标志编译我的 Fortran 代码,指定显式使用 double 。在 Fortran 中,这工作正常。当我将上面的代码编译为

f2py --f90flags="-fdefault-double-8 -fdefault-integer-8 -fdefault-real-8" -c -m mymod test.f90 

我得到结果

python -c "import mymod as m; print m.test1.a; print m.test2.a" 
 
0.0 
6789.0 

这其实很奇怪。全局变量在第一种情况下没有初始化,它的值为零。这是一个错误还是有不同的方法来指定 f2py 中 double 的显式处理?

请您参考如下方法:

您没有指定“显式使用 double ”——我认为您指定的是“隐式使用 double ”,而 numpy/f2py 无法知道数据类型。在这种情况下,f2py 很可能猜测数据类型是 float32,因此实际上只解释了(64 位)参数的前 32 位。如果将 double 字传递给需要 float 的函数,您会看到相同的效果:

program main 
  real*8 :: foo 
  foo = 12345. 
  call printme(foo) 
end program 
 
subroutine printme(foo) 
  real foo 
  print*, foo 
end subroutine printme 

编译运行:

gfortran test2.f90 
./a.out  #prints 0.00000 

这里的要点是您希望 f2py 知道如何解释 Fortran 代码以及如何解释特定编译器的命令行参数。我们可能会争辩说,这种类型的支持对于一小部分编译器很有用——不幸的是,f2py 目前不支持它。

您需要将所有参数和参数声明为特定类型,并且在命令行上更改它们可能会导致您在上面看到的各种错误。