为什么 f2py 在处理 inout 参数时没有生成正确的包装器?
这是我的函数调用的示例:
io = 7.5
io, out1, out2, out3 = fortran_file.func(5, 2.5, False, io)
这在 Fortran 中可能是这样的(example.f):
subroutine func(inputA, inputB, inputC, ioD, outE, outF, outG)
integer inputA
real inputB
logical inputC
real ioD, outE, outF, outG
real localH
if(.not.inputC) then
localH= ioD
else
localH= inputB
endif
ioD= ioD + localH
outE= inputA + 10.5
outF= inputA + 5.5
outG= inputA + 1.5
return
end
默认情况下,f2py 将此处的所有内容标记为输入,即使这是一个基本示例。所以我使用以下方法创建文件签名:
python.exe -m numpy.f2py -m fortran_file -h sig_example.pyf example.f
我编辑 pyf 文件以添加正确的意图信息。然后我编译使用:
python.exe -m numpy.f2py -c sig_example.pyf example.f
但它一直抱怨 f2py func 只返回 3 个项目。
即使 io 显式使用
intent(inout)
,f2py 也不会返回它。
我使用 f2py 中的
--build-dir
选项来查看为包装器生成的 C 代码。
该文件在参数下列出了 io,但它说 in/outputrank-0 array(float,'f)
这告诉我它知道它应该是 inout,但我不明白为什么它把它标记为数组?
它也没有在“返回”下列出 io,这让我更加困惑。
关联的 Py_BuildValue
调用也不将 io 包含在参数列表中。
为什么看起来 inout 不应该被返回? 这就是 inout 的全部意义,对于某些文件来说这是必需的。
我意识到这整个问题是小众的,但我真的可以在这里使用一些帮助。有没有办法在Python内部指定参数意图?因为我的文件太多了,无法手动编辑签名。
intent(inout)
参数的工作方式与 Fortran 中类似。然而,在Python中,Python环境中的变量值是不可变的。 Fortran 函数将收到一个副本,它将修改其副本,然后 Python 将丢弃修改后的副本。
但是可变值可以放入容器中,例如 NumPy 数组。这意味着
import numpy as np
io = np.asarray([7.5])
out, out, out = fortran_file.func(5, 2.5, False, io)
print(io)
将打印
[15.]
使用函数修改的新值。
@Vladimir F Героям слава 的帖子解决了我的问题。但是,它发布了如下警告:
DeprecationWarning:不推荐将 ndim > 0 的数组转换为标量,并且将来会出错。确保在执行此操作之前从数组中提取单个元素。 (已弃用 NumPy 1.25。)
还没有找到解决避免此警告的方法。