如何在循环中有效使用f2py?Fortran模块仅执行最后一次循环问题排查
循环调用f2py封装的Fortran模块仅执行最后一个案例的问题排查
问题背景
需通过f2py封装的Fortran模块ftmodule循环处理数千个命名为indus001.txt、indus002.txt……indusxxx.txt的文件。该模块的输入要求:
- 参数
Ln:对应输入文件的行数 - 输入文件:固定名为
temporaryfile.txt
模块输出为固定名outputfile.txt。
Python循环实现步骤:
- 使用
os.listdir遍历文件 - 通过
array.shape获取每个文件的行数ln - 用
np.savetxt将每个indusxxx.txt内容保存为temporaryfile.txt作为模块输入 - 调用Fortran模块
- 读取
outputfile.txt并保存为带序列标识的新文件
问题现象:Fortran模块单独运行正常,但循环中仅最后一个案例执行生效。
用户代码如下:
import numpy as np import os import pandas import ftmodule # This is the f2py module for i in os.listdir(): if i.startswith('indus'): # Read Indus parameters from text file. values = pandas.read_fwf(i, index_col=False, header=None) wine = pandas.DataFrame(values) array = np.array(wine) rows, colums = array.shape lines = rows np.savetxt("temporaryfile.txt",array.to_numpy(),fmt=['%7.0f', '%7.0f', '%7.2f','%7.2f','%7.2f','%7.2f','%10.1f']) deform = ftmodule.ftmodule2(ln=lines) #calling the fortran program newoutput = pandas.read_fwf('outputfile.txt', index_col=False, header=None) nw = pandas.DataFrame(newoutput) np.savetxt("Nw_{}".format(i),nw.to_numpy(),delimiter=' ', fmt='%6.2f')
注:希望尽量避免修改Fortran程序,仅通过Python实现循环;无法提供Fortran代码。
可能原因及解决方案
1. 文件操作未同步(缓存/未刷新)
Python写入temporaryfile.txt后,操作系统可能未将数据真正落盘,Fortran就读取了旧缓存内容;或Fortran输出outputfile.txt后,文件句柄未关闭,导致后续读取到旧数据。
解决办法:
- 改用
with语句写入临时文件,确保文件被正确关闭并刷新:
# 替换原np.savetxt行 with open("temporaryfile.txt", "w") as f: np.savetxt(f, array.to_numpy(), fmt=['%7.0f', '%7.0f', '%7.2f','%7.2f','%7.2f','%7.2f','%10.1f'])
- 调用Fortran模块后,短暂延迟确保输出文件写入完成(临时验证用):
import time deform = ftmodule.ftmodule2(ln=lines) time.sleep(0.1) # 给Fortran足够时间写入输出文件 newoutput = pandas.read_fwf('outputfile.txt', index_col=False, header=None)
2. 旧文件残留导致覆盖异常
如果循环中未清理旧的临时文件或输出文件,Fortran可能读取到上一次循环的残留内容,或输出被意外覆盖。
解决办法:
在每次写入临时文件前,删除旧的临时文件和输出文件:
# 清理旧文件 for fname in ["temporaryfile.txt", "outputfile.txt"]: if os.path.exists(fname): os.remove(fname) # 再写入新的临时文件 np.savetxt("temporaryfile.txt",array.to_numpy(),fmt=['%7.0f', '%7.0f', '%7.2f','%7.2f','%7.2f','%7.2f','%10.1f'])
3. 遍历顺序与处理验证
os.listdir()返回的文件顺序由操作系统决定,可能存在部分文件未被正确处理的情况。
验证办法:
在循环中加入打印语句,确认每个文件都进入处理流程:
print(f"Processing file: {i}, line count: {lines}")
同时检查rows的值是否与实际文件行数一致,排除读取文件时的格式解析错误。
4. 简化文件读取流程</think_never_used_51bce0c785ca2f68081bfa7d91973934>
可以跳过pandas,直接用numpy读取文件,减少中间环节的潜在问题:
# 替换原pandas读取部分 array = np.loadtxt(i) rows, columns = array.shape lines = rows
总结
优先排查文件缓存与清理问题,用with语句确保文件写入落盘,同时清理旧的临时文件和输出文件;其次验证每个文件是否都进入循环处理,确认行数读取正确;最后简化文件读取流程减少潜在异常。
内容的提问来源于stack exchange,提问作者trfyyt5766879
相关产品推荐
相关产品推荐

