Windows下调用Python配置读取函数出现FileNotFoundError问题求助
问题描述
项目结构
- Report - rep - common - config - Lines - static - templates
Lines目录下的Python代码
import yaml def read_conf(env='default'): data_list = {} # 存储配置 with open(r"../config/database.yaml", 'r', encoding='utf-8') as ymlfile: cfg = yaml.load_all(ymlfile, Loader=yaml.SafeLoader) for data in cfg: data_list.update(data) if env == 'pro': re = data['conf']['pro'] return re re = data['conf'][data[env]] return re if __name__ == '__main__': re = read_conf() print(re)
遇到的问题
直接运行该脚本时,能正常读取config目录下的database.yaml;但在其他文件中调用read_conf函数时,抛出错误:
FileNotFoundError: [Errno 2] No such file or directory: '../config/database.yaml'
期望跨文件调用该函数时,能返回格式为{'host': '', 'user': '', 'passwd': '', 'db': '', 'port': }的配置结果,使用Windows系统,需了解问题原因及解决方法。
问题原因及解决方案
问题原因
你使用的../config/database.yaml是相对路径,这个路径的基准是Python的当前工作目录(CWD),而非当前脚本文件的实际位置:
- 直接运行Lines目录下的脚本时,当前工作目录就是Lines目录,
../config能正确定位到上级目录的config文件夹; - 当其他文件调用这个函数时,当前工作目录是调用文件所在的目录(或执行Python命令时的起始目录),此时
../config不再是正确路径,自然找不到文件。
另外代码还有一处逻辑错误:循环结束后data仅保存yaml中最后一个文档的数据,但你后续用data['conf']取值,而前面已经把所有yaml数据合并到data_list里,这里应该用data_list而非data,否则会导致配置读取不完整。
解决方案
通过脚本文件的绝对路径拼接配置文件路径,这样无论当前工作目录是什么,都能精准定位到配置文件。修改后的代码如下:
import yaml import os def read_conf(env='default'): # 获取当前脚本的绝对路径 current_script_path = os.path.abspath(__file__) # 获取脚本所在目录 current_dir = os.path.dirname(current_script_path) # 拼接配置文件路径并标准化(自动处理Windows路径分隔符) config_path = os.path.normpath(os.path.join(current_dir, '../config/database.yaml')) data_list = {} with open(config_path, 'r', encoding='utf-8') as ymlfile: cfg = yaml.load_all(ymlfile, Loader=yaml.SafeLoader) for data in cfg: data_list.update(data) if env == 'pro': return data_list['conf']['pro'] return data_list['conf'][data_list[env]] if __name__ == '__main__': re = read_conf() print(re)
关键说明
os.path.abspath(__file__):获取当前脚本的绝对路径,不受工作目录变化影响;os.path.join:跨系统拼接路径,自动适配Windows的\和类Unix的/;os.path.normpath:将路径中的../等相对标识转换为标准绝对路径,避免路径解析错误。
内容的提问来源于stack exchange,提问作者Rain
相关产品推荐
相关产品推荐

