如何在Python读取Fortran文件时安全检查文件是否存在?
解决Fortran子routine错误传递到Python的问题
要解决文件不存在的竞态问题,核心是在Fortran代码中添加错误检查,并将错误转化为Python可捕获的异常,无需在Python端提前做文件存在性校验。
1. 修改Fortran代码(添加错误处理逻辑)
更新parse.f90,加入I/O错误检查,并通过f2py提供的接口抛出Python异常:
subroutine read_params(filename, params) implicit none ! Argument Declarations ! character(len=*), intent(in) :: filename integer, dimension(4), intent(out) :: params ! Variable Declarations integer :: i, ios ! f2py 用于抛出Python异常的外部函数 external pyerr_setstring character(len=256) :: err_msg ! 打开文件并检查错误:status="old"要求文件必须已存在 open(unit=1, status="old", file=filename, form="unformatted", & iostat=ios, iomsg=err_msg) if (ios /= 0) then ! 抛出Python IOError异常,携带错误信息 call pyerr_setstring("IOError", trim(err_msg)) return end if ! 读取参数并检查错误 read(1, iostat=ios, iomsg=err_msg) (params(i), i=1, 4) if (ios /= 0) then close(1) call pyerr_setstring("IOError", trim(err_msg)) return end if close(1) end subroutine read_params
关键修改点:
- 用
status="old"替代原status="unknown":确保文件不存在时直接触发open错误,避免创建空文件 - 添加
iostat(错误状态码)和iomsg(错误描述信息)参数,捕获I/O操作的异常 - 通过
pyerr_setstring外部函数,将Fortran的错误转化为Python标准异常(这里用IOError)
2. 重新编译Fortran模块
使用原编译命令重新生成Python可调用的模块:
python -m numpy.f2py -c -m parse parse.f90
3. Python端捕获并处理异常
修改Python代码,直接调用子routine并捕获异常,无需提前检查文件存在:
from pathlib import Path from .parse import read_params def do_stuff_with_params(path: Path): try: # 部分f2py版本需将Path转为字符串传入 params = read_params(str(path)) # 此处处理参数逻辑 return params except IOError as e: # 按需处理异常,比如打印日志或重新抛出 print(f"文件读取失败:{e}") raise
这样一来,无论文件是在调用前被删除,还是读取过程中出现错误,都会直接抛出Python异常,从根本上避免了竞态问题,同时减少了冗余的检查逻辑。
内容的提问来源于stack exchange,提问作者DeltaIV
相关产品推荐
相关产品推荐

