这是我想在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
输出2个电话:
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)
输出2个电话:
10
1686728152
第二个数字是随机的。
我尝试以不同的方式在python中分配,np.empty_like,np.zeros。没有帮助。我认为问题在于如何分配iwk数组(因此问题标题),但不确定。我需要改变什么来使它工作?最好,我只想更改python脚本并保留Fortran代码。
答案 0 :(得分:3)
告诉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)
,...)。