2012-11-19 70 views
5

假設我們需要在python程序中調用fortran函數,它返回一些值。我發現,改寫Fortran代碼以這樣的方式:製作python和fortran朋友

subroutine pow2(in_x, out_x) 
     implicit none 
     real, intent(in)  :: in_x 
!f2py real, intent(in, out) :: out_x 
     real, intent(out)  :: out_x 
     out_x = in_x ** 2 
     return 
end 

,在這種方式調用它的Python:

import modulename 
a = 2.0 
b = 0.0 
b = modulename.pow2(a, b) 

給了我們工作的結果。我能否以其他方式調用fortran函數,因爲我認爲第一種方法有點笨拙?

+0

考慮使用IPython? – inspectorG4dget

+0

它如何幫助我?據我所知,這是一種升級的交互模式。 – user983302

+1

它還允許您與其他程序(如R,MATLAB和FORTRAN)連接。看看[這個視頻](http://pyvideo.org/video/1605/science-and-python-retrospective-of-a-mostly-s) – inspectorG4dget

回答

10

我想你只需要稍微改變你的f2py函數簽名(這樣out_x只有intent(out)in_x只有intent(in)):

subroutine pow2(in_x, out_x) 
    implicit none 
    real, intent(in) :: in_x 
    !f2py real, intent(in) :: in_x 
    real, intent(out)  :: out_x 
    !f2py real, intent(out) :: out_x 
    out_x = in_x ** 2 
    return 
end subroutine pow2 

現在編譯:

f2py -m test -c test.f90 

現在運行:

>>> import test 
>>> test.pow2(3) #only need to pass intent(in) parameters :-) 
9.0 
>>> 

注意,在這種情況下,f2py能夠正確掃描功能的簽名不特殊!f2py評論:

!test2.f90 
subroutine pow2(in_x, out_x) 
    implicit none 
    real, intent(in) :: in_x 
    real, intent(out)  :: out_x 
    out_x = in_x ** 2 
    return 
end subroutine pow2 

編譯:

f2py -m test2 -c test2.f90 

運行:

>>> import test2 
>>> test2.pow2(3) #only need to pass intent(in) parameters :-) 
9.0 
>>> 
+0

哇,太棒了!這種方式甚至可以返回元組中的多個變量!正因爲我的好奇心,如果還有其他一些技巧,我現在不會選擇這個答案。 – user983302

+0

我常常對使用'f2py'打包fortran代碼的容易程度印象深刻。正因爲如此,我從來沒有想過要學習任何python C API甚至是'Cython',儘管在某些時候我想要學習這些技巧。 – mgilson

0

avoi的另一個好處丁intent(inout)的論點是(與一些其他限制)由此產生的功能can be considered PURE。這與功能語言採用的無副作用方法有關,並且Fortran編譯器提供了更好的優化和錯誤檢測,對於自動並行化尤其重要。

0

如果您使用IPython的,試試神奇的命令,這使得它能夠寫出

%%fortran 
subroutine pow2(in_x, out_x) 
    implicit none 
    real, intent(in) :: in_x 
    real, intent(out)  :: out_x 
    out_x = in_x ** 2 
    return 
end subroutine pow2 

,然後簡單地在你的代碼中使用此功能(無需額外的進口)。