如何规范且安全地从非当前目录打开非Python文件?(pytest场景)
规范安全地跨目录读取非Python文件的方法
要解决这个问题,核心是不要依赖当前工作目录的相对路径——因为你两种运行方式的工作目录不一样(一种是tests/目录,一种是项目根目录),相对路径会直接失效。正确的做法是基于测试脚本自身的位置来构建绝对路径,这样不管从哪里运行,都能精准定位到目标文件。
假设你的项目结构是这样的(如果实际结构有差异,只需调整路径层级即可):
project-pytest/ ├── schema.json ├── runner_01.cmd └── tests/ └── file_with_tests.py
下面是两种推荐的实现方式:
方法1:使用pathlib(Python 3.4+ 推荐)
pathlib是Python3引入的面向对象路径处理模块,语法简洁直观,是当前的最佳实践:
from pathlib import Path import json # 获取当前测试脚本所在的目录(即tests/目录) test_dir = Path(__file__).parent # 向上一级找到项目根目录 project_root = test_dir.parent # 拼接schema文件的绝对路径 schema_file = project_root / "schema.json" # 安全读取文件 with open(schema_file, "r", encoding="utf-8") as f: schema = json.load(f)
关键逻辑解释:
__file__:Python会自动设置这个变量,指向当前脚本的路径(可能是相对或绝对路径),通过Path(__file__)转为路径对象后就能方便操作。.parent:获取路径对象的父目录,比如tests/file_with_tests.py的父目录就是tests/。- 用
/运算符拼接路径,比字符串拼接更安全,自动适配Windows/Linux的路径分隔符,不会出现手动拼接的错误。
方法2:使用os.path(兼容旧Python版本)
如果需要兼容Python2或者习惯传统路径处理方式,可以用os模块实现相同逻辑:
import os import json # 获取当前脚本的绝对路径,避免相对路径歧义 test_file_path = os.path.abspath(__file__) # 获取脚本所在的目录(tests/) test_dir = os.path.dirname(test_file_path) # 向上一级找到项目根目录 project_root = os.path.dirname(test_dir) # 安全拼接schema文件路径 schema_file = os.path.join(project_root, "schema.json") # 安全读取文件 with open(schema_file, "r", encoding="utf-8") as f: schema = json.load(f)
关键逻辑解释:
os.path.abspath(__file__):确保拿到的是脚本的绝对路径,消除不同运行场景下的路径歧义。os.path.dirname():连续调用两次,从脚本路径一步步定位到项目根目录。os.path.join():自动处理不同系统的路径分隔符,避免手动拼接出现\和/混用的问题。
额外注意事项
- 验证路径正确性:可以临时在代码里加入
print(schema_file),运行测试时确认输出的路径是否指向正确的schema.json文件,方便调试。 - 复用路径逻辑:如果多个测试文件都需要读取schema,建议把路径构建的逻辑封装成函数,放在
tests/目录下的公共模块(比如conftest.py或者utils.py)里,避免重复代码。 - 指定编码:打开文件时加上
encoding="utf-8",避免不同环境下的编码乱码问题,让文件读取更稳定安全。
这样不管你是在tests/目录下运行python -m pytest file_with_tests.py,还是在项目根目录通过runner_01.cmd执行python -m pytest -v .\tests\file_with_tests.py,都能正确找到并读取schema.json文件。
内容的提问来源于stack exchange,提问作者ornichola
相关产品推荐
相关产品推荐

