这是我想在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代码不变.
解决方法:
您告诉python数组是intent(in)的:
integer iwk(31*ndp + nip)
!f2py intent(in) :: iwk
您无权更改,并希望更改将保留.可能您想要intent(inout).
更好的是,忘记!f2py的意图并直接使用:
integer, intent(inout) :: iwk(31*ndp + nip)
如果尝试修改intent(in)变量,编译器会告诉您您是错误的.
注意在Python中使用正确的dtype,它必须与Fortran类型相对应.大多数情况下,Fortran整数等效于int32,但有时也可能是int64.您也可以在Fortran中对其进行控制(整数* 4,整数(int32)等).