使用f2py编译后获取模块没有属性错误
getting module has no attribute error after compiling with f2py
我 运行 遇到了一个问题,同时尝试使用 f2py(在 gfort运行 中)使一堆 Fort运行 代码在 Python 中工作。我的 Fort运行 代码有一大堆子例程,它在 gfort运行 和在线虚拟 fort运行 IDE 中都编译得很好。
我遇到问题的子例程是合并排序子例程(我从 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
我用
编译了它
$ f2py -c -m fprogram fprogram.f90
并在我的 python 代码的开头插入 import fprogram
(在 jupyter 笔记本中),我想像这样使用它的地方(我知道原始是一个列表,这不是维度问题):
size=len(original_list)
sorted_list=fprogram.MSort(size,original_list)
我收到错误消息
module 'fprogram' has no attribute 'MSort'
与此同时,当我以相同的方式使用 fprogram 中的任何其他子例程时,它工作得很好。
我已经将 fort运行 代码修改为不包含带有 intent(inout)
的变量,因为在之前的案例中这已经解决了我的问题,但这次没有用。我该怎么做才能让 python 识别这个子例程?
有 2 个不同的错误。
首先,f2py
创建所有小写程序。
因此,您需要调用 fprogram.msort
,这正是错误消息试图告诉您的内容。
另一方面,f2py
发现参数 N
在 python 中是多余的。
这就是为什么它创建了一个函数,其中 N
是一个可选参数。
因此,您还需要通过以下方式之一调用它
sorted_list=fprogram.msort(original_list)
sorted_list=fprogram.msort(original_list, size)
sorted_list=fprogram.msort(original_list, n=size)
我是怎么发现的?
我通过调用(在 python REPL 中)
来阅读文档
import fprogram
help(fprogram)
我 运行 遇到了一个问题,同时尝试使用 f2py(在 gfort运行 中)使一堆 Fort运行 代码在 Python 中工作。我的 Fort运行 代码有一大堆子例程,它在 gfort运行 和在线虚拟 fort运行 IDE 中都编译得很好。 我遇到问题的子例程是合并排序子例程(我从 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
我用
编译了它$ f2py -c -m fprogram fprogram.f90
并在我的 python 代码的开头插入 import fprogram
(在 jupyter 笔记本中),我想像这样使用它的地方(我知道原始是一个列表,这不是维度问题):
size=len(original_list)
sorted_list=fprogram.MSort(size,original_list)
我收到错误消息
module 'fprogram' has no attribute 'MSort'
与此同时,当我以相同的方式使用 fprogram 中的任何其他子例程时,它工作得很好。
我已经将 fort运行 代码修改为不包含带有 intent(inout)
的变量,因为在之前的案例中这已经解决了我的问题,但这次没有用。我该怎么做才能让 python 识别这个子例程?
有 2 个不同的错误。
首先,f2py
创建所有小写程序。
因此,您需要调用 fprogram.msort
,这正是错误消息试图告诉您的内容。
另一方面,f2py
发现参数 N
在 python 中是多余的。
这就是为什么它创建了一个函数,其中 N
是一个可选参数。
因此,您还需要通过以下方式之一调用它
sorted_list=fprogram.msort(original_list)
sorted_list=fprogram.msort(original_list, size)
sorted_list=fprogram.msort(original_list, n=size)
我是怎么发现的? 我通过调用(在 python REPL 中)
来阅读文档import fprogram
help(fprogram)