python - 在python项目中使用相对路径读取文件

标签 python python-3.x io relative-path python-import

假设我有一个结构如下的 python 项目:

project
    /data
        test.csv
    /package
        __init__.py
        module.py
    main.py
__init__.py :
from .module import test
module.py :
import csv

with open("..data/test.csv") as f:
    test = [line for line in csv.reader(f)]
main.py :
import package

print(package.test)

当我运行 main.py我收到以下错误:
 C:\Users\Patrick\Desktop\project>python main.py
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    import package
  File "C:\Users\Patrick\Desktop\project\package\__init__.py", line 1, in <module>
    from .module import test
  File "C:\Users\Patrick\Desktop\project\package\module.py", line 3, in <module>
    with open("../data/test.csv") as f:
FileNotFoundError: [Errno 2] No such file or directory: '../data/test.csv'

但是,如果我运行 module.py来自 package目录我没有错误。所以看来open(...)中使用的相对路径仅相对于原始文件的运行位置(即 __name__ == "__main__" )?我不想使用绝对路径。有什么方法可以解决这个问题?

最佳答案

相对路径是相对于 current working directory .
如果你不希望你的路径是,它必须是绝对的。
但是有一个常用的技巧来从当前脚本构建绝对路径:使用它的 __file__ 特殊属性:

from pathlib import Path

path = Path(__file__).parent / "../data/test.csv"
with path.open() as f:
    test = list(csv.reader(f))
这需要 python 3.4+(对于 pathlib 模块)。
如果您仍然需要支持旧版本,您可以通过以下方式获得相同的结果:
import csv
import os.path

my_path = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(my_path, "../data/test.csv")
with open(path) as f:
    test = list(csv.reader(f))
[ 2020年编辑: python3.4+ 现在应该是规范,所以我首先移动了受 jpyams 评论启发的 pathlib 版本]

关于python - 在python项目中使用相对路径读取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69715777/

相关文章:

python - PythonKit错误“找不到Python库。设置PYTHON_LIBRARY环境变量和Python库的路径”

java - 扫描仪在使用 next() 或 nextFoo() 后跳过 nextLine()?

无法将双数正确导入到 C 程序中

python - 没有名为 cairo 的模块 - python 和 pip

python - request() 得到了一个意外的关键字参数 'json'

python - 两列之间的模糊匹配(Python)

python - 访问Python列表中的特定变量

python - Python 列表中的交替方向 - 更多 Pythonic 解决方案

c# - c# 和 java 之间的基准测试和差异原因

javascript - 如何使用 Python、JavaScript 或 Robot Framework 和 Selenium 使用部分标题文本导航到新的浏览器窗口