Python自定义包内读取文件报错:为何无法读取包内文件?
自定义Python包内文件读取失败问题解析
问题背景
自定义Python包结构如下:
mypackage | |-> __init__.py | |-> module1.py | |-> module2.py | |-> module3.py | |-> externalfile.xml
externalfile.xml由module1.py中的myfunction函数读取。直接在终端运行module1.py时可正常读取文件,但在外部脚本myOtherScript.py中调用该函数时,出现FileNotFoundError报错。
相关代码
module1.py
[...] def myfunction(): with open('externalfile.xml', 'r') as fh: xml = fh.read() return xml
init.py
import mypackage.module1 [...]
myOtherScript.py
from mypackage import module1 [...] script = module1.myfunction()
报错信息
Traceback (most recent call last): File --myOtherScript.py--, line xx, in <module> from mypackage import module1 File "-\Programs\Python\Python310\lib\site-packages\mypackage\__init__.py", line xx, in <module> with open('exeternalfile.xml', 'r') as fh: FileNotFoundError: [Errno 2] No such file or directory: 'externalfile.xml'
问题原因
核心是相对路径的基准目录不一致:
- 直接运行
module1.py时,Python的当前工作目录是mypackage文件夹(即脚本所在目录),此时'externalfile.xml'是相对于该目录的路径,能正确找到文件。 - 外部脚本调用时,当前工作目录是外部脚本
myOtherScript.py所在的文件夹,而非mypackage目录,此时使用相对路径'externalfile.xml'会在外部脚本目录下查找,自然找不到包内的文件。
解决方案
必须基于包本身的路径构建资源文件的绝对路径,而非依赖不确定的当前工作目录。推荐两种实现方式:
方法1:使用os模块(兼容所有Python版本)
修改module1.py中的myfunction:
import os def myfunction(): # 获取当前模块文件的绝对路径 module_abspath = os.path.abspath(__file__) # 获取模块所在的包目录 package_dir = os.path.dirname(module_abspath) # 拼接xml文件的绝对路径 xml_file_path = os.path.join(package_dir, 'externalfile.xml') with open(xml_file_path, 'r') as fh: xml = fh.read() return xml
方法2:使用pathlib模块(Python3.4+推荐)
pathlib提供更简洁的路径操作API:
from pathlib import Path def myfunction(): # 获取当前模块所在的包目录 package_dir = Path(__file__).parent # 拼接xml文件路径(支持/运算符) xml_file_path = package_dir / 'externalfile.xml' with open(xml_file_path, 'r') as fh: xml = fh.read() return xml
内容的提问来源于stack exchange,提问作者Nicola Vitali
相关产品推荐
相关产品推荐

