[英]getting module has no attribute error after compiling with f2py
I have ran into a problem, while trying to make a bunch of Fortran code work in Python using f2py (in gfortran).我在尝试使用 f2py(在 gfortran 中)使一堆 Fortran 代码在 Python 中工作时遇到了一个问题。 My Fortran code has a whole bunch of subroutines and it compiles fine both in gfortran and an online virtual fortran IDE.
我的 Fortran 代码有一大堆子程序,它在 gfortran 和在线虚拟 fortran IDE 中都能正常编译。 The subroutine I'm having issues with is a mergesort subroutine (which I took from rosettastone and modified), it looks like this:
我遇到问题的子例程是一个合并排序子例程(我从 Rosettastone 获取并修改),它看起来像这样:
subroutine MSort(N, A, A_out)
implicit none
integer, intent(in) :: N
real, dimension(N), intent(in) :: A
real, dimension(N), intent(out) :: A_out
real :: work((size(A) + 1) / 2)
A_out=A
call MergeSort(A_out, work)
contains
subroutine merge(A, B, C)
implicit none
real, target, intent(in) :: A(:), B(:)
real, target, intent(inout) :: C(:)
integer :: i, j, k
if (size(A) + size(B) > size(C)) then
stop
end if
i = 1; j = 1
do k = 1, size(C)
if (i <= size(A) .and. j <= size(B)) then
if (A(i) <= B(j)) then
C(k) = A(i)
i = i + 1
else
C(k) = B(j)
j = j + 1
end if
else if (i <= size(A)) then
C(k) = A(i)
i = i + 1
else if (j <= size(B)) then
C(k) = B(j)
j = j + 1
end if
end do
end subroutine merge
subroutine swap(x, y)
implicit none
real, intent(inout) :: x, y
real :: tmp
tmp = x; x = y; y = tmp
end subroutine
recursive subroutine MergeSort(A, work)
implicit none
real, intent(inout) :: A(:)
real, intent(inout) :: work(:)
integer :: half
half = (size(A) + 1) / 2
if (size(A) < 2) then
continue
else if (size(A) == 2) then
if (A(1) > A(2)) then
call swap(A(1), A(2))
end if
else
call MergeSort(A( : half), work)
call MergeSort(A(half + 1 :), work)
if (A(half) > A(half + 1)) then
work(1 : half) = A(1 : half)
call merge(work(1 : half), A(half + 1:), A)
endif
end if
end subroutine MergeSort
end subroutine MSort
I compiled it with我用它编译了
$ f2py -c -m fprogram fprogram.f90
and inserted import fprogram
in the beginning of my python code (in a jupyter notebook), where I wanted to use it like this (I know original is a list, it's not dimensional issues):并在我的 python 代码(在 jupyter 笔记本中)的开头插入了
import fprogram
,我想像这样使用它(我知道 original 是一个列表,它不是尺寸问题):
size=len(original_list)
sorted_list=fprogram.MSort(size,original_list)
I got the error message我收到错误消息
module 'fprogram' has no attribute 'MSort'
Meanwhile, when I used any other subroutine from fprogram in the same way it works perfectly.同时,当我以同样的方式使用 fprogram 中的任何其他子程序时,它可以完美运行。 I already modified the fortran code to not have variables with
intent(inout)
because in a previous case this has solved my problem, but it didn't work this time.我已经将 fortran 代码修改为没有带有
intent(inout)
的变量,因为在以前的情况下,这已经解决了我的问题,但这次没有用。 What I can I do to make python recognze this subroutine?我该怎么做才能让 python 识别这个子程序?
There are 2 different errors.有2个不同的错误。
At first, f2py
creates all lowercase procedures.首先,
f2py
创建所有小写程序。 Thus, you need to call fprogram.msort
which is exactly what the error message tries to tell you.因此,您需要调用
fprogram.msort
,这正是错误消息试图告诉您的内容。
On the other hand, f2py
figured out that the argument N
is redundant in python.另一方面,
f2py
发现参数N
在 python 中是多余的。 Which is why it created a function where N
is an optional paramenter.这就是它创建 function 的原因,其中
N
是可选参数。 Thus, you also need to call it in one of the following ways因此,您还需要通过以下方式之一调用它
sorted_list=fprogram.msort(original_list)
sorted_list=fprogram.msort(original_list, size)
sorted_list=fprogram.msort(original_list, n=size)
How did I find that out?我是怎么发现的? I read the documentation by calling (in the python REPL)
我通过调用(在 python REPL 中)阅读了文档
import fprogram
help(fprogram)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.