最近在写一个Python项目的时候遇到了一个很常见但是一直没有想清楚的问题,就是Python项目不同包中函数的引用会报错的问题。
问题描述:
这里我的根目录是E:\Lab\TEP-KG(项目地址)
整体的目录情况是这样的:
我希望在pca文件夹下的pca.py调用utils.tep_nmi里面的一个函数,即tep_dataset_read
运行时候就会报找不到路径的错误。
解决办法:
py文件运行环境:
这里我网上收集了很多资料,找到最有效的解决办法如下:
import sys
from pathlib import Path
# 保证绝对路径可以被检测到
current_file_path = Path(__file__).parent.absolute() # 获取当前文件的绝对路径
project_root_path = current_file_path.parent # 获取项目根目录的路径
sys.path.append(str(project_root_path)) # 将项目根目录添加到 sys.path
from utils.tep_nmi import tep_dataset_read #这一行换成你的引用函数
实际上做了一件简单的事情,就是把当前目录的根目录加入到sys.path中
比如我运行pca.py时目录为E:\Lab\TEP-KG\pca
其根目录为E:\Lab\TEP-KG,而在这个根目录下你可以检索到utils这个包,就解决了问题
代码中的变量project_root_path即为根目录为E:\Lab\TEP-KG
注意:为了保证utils可以被正确识别为一个包,你可以在utils目录下添加一个空文件即__inti__.py
ipynb文件运行环境:
在我的目录下的pca.ipynb运行环境下,会报这样的错误:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_99332\2766759517.py in <module>
2 from pathlib import Path
3 # 保证绝对路径可以被检测到
----> 4 current_file_path = Path(__file__).parent.absolute() # 获取当前文件的绝对路径
5 project_root_path = current_file_path.parent # 获取项目根目录的路径
6 sys.path.append(str(project_root_path)) # 将项目根目录添加到 sys.path
NameError: name '__file__' is not defined
这里一个简单的方式是直接用最后一句代码来实现:
sys.path.append('E:\Lab\TEP-KG') # 将项目根目录添加到sys
这里的E:\Lab\TEP-KG即为可以检测到utils包的根目录
如果觉得不美观,不通用,可以转成这种写法:
sys.path.append("\\".join(sys.path[0].split("\\")[:-1]))
sys.path[0]一般是当前的运行目录的str,取它的上一级目录即可,和直接写E:\Lab\TEP-KG是等价的。
相对路径调用的局限性:
如果在utils目录下的其他文件,可以采用相对路径写法来实现函数调用:
from tep_nmi import tep_dataset_read
如果在主函数目录下,如main.py,也可以采用相对路径写法来实现函数调用:
from utils.tep_nmi import tep_dataset_read
但是存在另一个问题,如果在utils的另一个py文件下采用相对调用,而主函数main.py想调用这个函数时,就会自动运行此py文件下的相对调用代码,效果即为在main.py下运行:
from tep_nmi import tep_dataset_read
那肯定会报相对路径的错误,所以这样的相对路径调用方式无法完成两次调用,而采用上述的绝对路径调用,则可以很好地解决两次调用的问题。