8

を使用して Fortran で Python モジュールを作成していf2pyます。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、 の各要素に追加しますaa(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 コードは続行されません。

4

2 に答える 2

4

numpyf2py の「強化」 ( ) を追加することをコミュニティに提案しました。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 から例外を発生させる非常に便利な方法だと思います。私の提案を githubに載せました。

于 2015-10-21T10:19:05.700 に答える