我使用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程序员(在打卡的那一天回来!)。所以,请回答一个老家伙可以遵循的事情。
感谢您的帮助。
PunchDaddy
答案 0 :(得分: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
导入模块中的所有子例程。