我正在使用f2py
在Fortran中创建一个Python模块。如果在Fortran模块中遇到错误,我想在Python程序中产生错误(包括错误消息)。请考虑以下示例:
Fortran代码(test.f):
subroutine foo(a,m)
integer :: m,i
integer, dimension(m) :: a
!f2py intent(in) :: m
!f2py intent(in,out) :: a
!f2py intent(hide), depend(a) :: m=shape(a)
do i = 1,m
if ( a(i) .eq. 0 ) then
print*, 'ERROR HERE..?'
end if
a(i) = a(i)+1
end do
end subroutine
这个非常简单的程序会为1
的每个元素添加a
。但如果a(i)
等于零,则会产生错误。随附的Python代码:
import test
print test.foo(np.array([1,2],dtype='uint32'))
print test.foo(np.array([0,2],dtype='uint32'))
输出现在是:
[2 3]
ERROR HERE..?
[1 3]
但我希望Python程序能够解决错误。请帮忙。
答案
Fortran中的stop
命令就是这样做的。考虑更新的Fortran代码:
subroutine foo(a,m)
integer :: m,i
integer, dimension(m) :: a
!f2py intent(in) :: m
!f2py intent(in,out) :: a
!f2py intent(hide), depend(a) :: m=shape(a)
do i = 1,m
if ( a(i) .eq. 0 ) then
print*, 'Error from Fortran'
stop
end if
a(i) = a(i)+1
end do
end subroutine
输出现在是:
[2 3]
Error from Fortran
即。错误之后,Python代码不会继续。
答案 0 :(得分:3)
我建议numpy
社区添加一个额外的f2py“增强”(raise_python_exception
),这样就可以在Fortran中定义一个字符串变量,如果非空将导致Python一旦函数返回就引发异常。
所以在Fortran你会写一些类似的东西:
subroutine calc_dq(q, temp, dq, error_mesg)
!f2py raise_python_exception error_mesg
real, intent(in) :: q, temp
real, intent(out) :: dq
character(len=100), intent(out) :: error_mesg
if (.not. init_called()) then
error_mesg = "`init` hasn't been called."
else
call q_flux_function(q, temp, dq)
endif
end subroutine calc_dq
从Python调用error_mesg
变量的内容用作异常的内容:
In [2]: calc_dq(1.0, 300.)
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
<ipython-input-8-c0ce0cb9cda1> in <module>()
----> 1 calc_dq(1.0, 300.)
Exception: `init` hasn't been called.
我认为这是从Fortran引发异常的一种非常方便的方法,因为它允许轻松定义异常消息。我放了我的suggestion on github。
答案 1 :(得分:1)
f2py
确实提供了一些可用于引发异常的语句。详情请见:
http://cens.ioc.ee/projects/f2py2e/usersguide/#statements
请特别注意callstatement
,其中介绍了如何添加会引发异常的f2py_success = 0
。
我不确定这会帮助你调试fortran库的内部,但至少它是一个开始。