下面是我想在python中调用的Fortran子例程中的一个最小化片段。任务很简单。第一次调用代码时,将值分配给数组iwk的第一个条目。然后第二次调用子例程,预期的行为是分配的条目保持不变。
subroutine testf2py (md,iwk,ndp,nip)
implicit none
integer ndp
!f2py intent(in) :: ndp
integer nip
!f2py intent(in) :: nip
integer iwk(31*ndp + nip)
!f2py intent(in) :: iwk
integer md
!f2py intent(in) :: md
if ( md == 1 ) then
iwk(1) = ndp
end if
print*, iwk(1)
end(第一个调用: md=1,随后调用: md>1)。数组iwk应该在python中分配,数组中的值应该在调用之间保持不变。在Fortran中调用此函数没有问题:
program main
implicit none
integer :: i, ndp, nip
integer, allocatable :: iwk(:)
ndp = 10
nip = 10
allocate(iwk(31*ndp+nip))
call test (1, iwk, ndp, nip)
call test (2, iwk, ndp, nip)
end program main两个呼叫的输出:
10
10在python中,在用f2py编译子例程之后,它无法工作。iwk中的值变化如下:
import testf2py
import numpy as np
ndp = 10
nip = 10
iwk = np.empty([31*ndp+nip,], dtype=int, order='F')
testf2py.test(1, iwk, ndp, nip)
testf2py.test(2, iwk, ndp, nip)两个呼叫的输出:
10
1686728152 第二个数字是随机的。
我试着用不同的方式分配python,np.empty_like,np.zeros。帮不上忙。我假设问题在于如何分配iwk数组(因此出现了问题标题),但不确定。我要改变什么才能让它发挥作用?最好,我只想更改python脚本,并保留Fortran代码的原样。
发布于 2015-01-28 16:34:14
告诉python数组是intent(in)
integer iwk(31*ndp + nip)
!f2py intent(in) :: iwk 您不允许更改它,并期望更改将被保留。也许你想要intent(inout)。
更好的是,忘记!f2py intent并直接使用:
integer, intent(inout) :: iwk(31*ndp + nip)如果你试图修改一个intent(in)变量,编译器会告诉你你错了。
在Python中要小心使用正确的dtype,它必须对应于Fortran类型。大多数情况下,Fortran integer等同于int32,但有时可能是int64。您也可以在Fortran中控制这一点(integer*4,integer(int32),.)。
https://stackoverflow.com/questions/28194358
复制相似问题