0

我使用 f2py (inputUtil.pyd) 在 python 中编译了一个 fortran 代码。我将此函数导入到我的主要 python 代码中,并从字符串中将两个字符(locationAID 和 locationBID)传递给此函数。

这是错误消息:

>>> Traceback (most recent call last):
  File "C:\FROM_OLD_HD\SynBio\Contact 5-23-12\contactsource_workingcopy\python\main.py", line 234, in batchExecute
    self.prepareProteins(tempList[1].replace("protA: ",""),tempList[2].replace("protAID: ",""),tempList[3].replace("protB: ",""),tempList[4].replace("protBID: ",""))
  File "C:\FROM_OLD_HD\SynBio\Contact 5-23-12\contactsource_workingcopy\python\main.py", line 668, in prepareProteins
    total = inputUtil(locationAID,locationBID)
NameError: global name 'inputUtil' is not defined

以下是我的主要 python 代码的一部分:

#import fortran modules
from contact import *
from inputUtil import *

....
def prepareProteins(self, locationA, locationAID, locationB, locationBID):
    self.output("Generating temporary protein files...")
    start_time = time.time()

    shutil.copyfile(locationA,"."+os.sep+"prota.pdb")
    shutil.copyfile(locationB,"."+os.sep+"protb.pdb")


    total = inputUtil(locationAID,locationBID)
...

这是我使用 f2py 转换为 python 的部分 fortran 代码,它显示了传递给此函数的字符:

     subroutine inputUtil(chida,chidb)
c
       integer resnr,nbar,ljnbar,ljrsnr
       integer resns,nbars
       integer resnc,nbarc
       integer resnn,nbarn
c
       integer numa,numb,ns,n
c
       character*6 card,cards,cardc,cardn,ljcard
c
       character*1 alt,ljalt,chid,ljchid,code,ljcode
       character*1 alts,chids,codes
       character*1 altc,chidc,codec
       character*1 altn,chidn,coden
       character*1 chida,chidb
....

f2py 工作得很好,所以我认为这不是问题。我只是在学习 python - 我是一个老 Fortran 程序员(从打孔卡的那天开始!)。所以,请回复一些老人可以遵循的东西。

谢谢你的帮助。

打孔爸爸

4

1 回答 1

1

我认为您在这里混淆了功能和模块。当你做from inputUtil import *然后调用inputUtil时,那和调用函数是一样的inputUtil.inputUtil

我在您提供的 Fortran 代码上运行了 f2py,并增加了一行:print*, "hello from fortran!". 我还必须删除 C 注释行,大概是因为我使用了.f90. 这是我使用的命令:

python "c:\python27\scripts\f2py.py" -c --fcompiler=gnu95 --compiler=mingw32 -lmsvcr71 -m inputUtil inputUtil.f90

现在我应该得到一个名为 inputUtil 的 python 模块。让我们试试看。简单的 Python:

import inputUtil
inputUtil.inputUtil('A', 'B')

从这里我得到:

AttributeError: 'module' object has no attribute 'inputUtil'

发生什么了?让我们看一下模块:

print dir(inputUtil)

这将返回:

['__doc__', '__file__', '__name__', '__package__', '__version__', 'inpututil']

显然 inputUtil 中的大写 U 已转换为小写。让我们用小写的名字调用函数:

inputUtil.inpututil('A', 'B')

现在它打印:

hello from fortran!

成功!

看起来将函数名称转换为小写可能是 f2py 的问题/功能。我从来没有遇到过它,因为我通常使用小写名称。

为了将来参考,我还建议将 Fortran 放在一个模块中,并将intent语句添加到您的子例程参数中。这将更容易在 f2py 模块和 Python 之间传递变量。像这样包裹在一个模块中:

module inpututils

contains

subroutine foo(a, b)
...code here...
end subroutine

end module

然后,您从模块中导入所有子例程,并use inpututils在另一个文件中的子例程顶部(之前implicit none)。

于 2013-04-11T21:42:40.573 回答