在做大型工程项目的时候,跨目录调用文件是我们要经常面临的问题,方法有绝对目录和相对目录两种,绝对目录是比较简单的,相对目录相对比较难理解,并且其中有很多坑。对于一些刚开始用pycharm的朋友来说,如何理解跨目录调用的相对路径是一个比较棘手的问题,目前网上也没有人说的特别清楚,笔者就结合自己的经验来给大家讲一讲。
1. 在文件调用中的应用
相对路径即通过.方式回退,一个.代表上一级目录,..代表再上一级目录,以此类推最终得到目标文件。举个例子来说吧,我现在有下图这么一个工程文件。
例子1
我现在想要在gbdt项目下的regressiontree.py文件里调用kmeans下的xigua.txt数据。根据上文说的原则,可以写以下代码,测试通过:
with open(r'../kmeans/xigua.txt') as f:
for line in f.readlines()[1:]:
data_line = line.strip().split(',')
data_line = list(map(float, data_line))
base_data.append(data_line)
print(base_data)
解释以下就是一个.回到gbdt同级目录,..回到gbdt再上一级目录,然后在上一级目录切换到/kmeans下读取/xigua.txt。
但是这里又有一个问题,就是假设你某个py文件里用相对路径读入了某个文件,你单独运行这个py文件是没问题的,但是要通过导入的方式运行就会出现错误。这个点大家一定要注意,在工程项目如果非要在子程序读文件,一定用绝对路径。
2 在模块导入中的应用
模块导入是什么意思呢,还是以上面的例子1来说明,现在是gbdt下的regressiontree.py文件要导kmeans下的kmeanshandwrite.py文件里的所有函数,最稳妥的方法当然还是绝对导入,就是从根目录开始一级级导入。给大家上一个比较完整的工程目录图,其实就是我自己练习的一个目录。
例子2
如果是绝对引用,用下面这句话:
from algorithm.kmeans.kmeans_handwrite import *
如果是相对引用,用下面这句话,含义和上面说的引入文件一样的
from ..kmeans.kmeans_handwrite import *
但是如果你用相对引用,直接运行这个py文件时候,你会喜提错误一个:
ValueError: attempted relative import beyond top-level package
这个错误是最常遇到的错误,简单点说就是因为你把当前文件作为主程序运行了,那么当前文件所在的文件夹就不是一个python package了,既然不是一个package你在用..寻找它的上层目录,自然是找不到了,因为它自己不是一个包啊。这个怎么办呢,其实解决思路很简单:
单独定义一个run.py或者main.py文件,从这里运行,那么regressiontree所在的gbdt就是一个python package了,自然就有上一层了,可以用相对引用了。但是一定要记住,run.py和main.py里导包一定要用绝对路径导入,要不然就犯和上面一样的错误了。话不多说,其实就是新建一个mian.py,加入下面的语句,绝对就成功了:
from algorithm.gbdt.regressiontree import *
3.总结
工程项目里使用相对路径是一个比较危险的事,但是由于你的项目路径经常变动使用相对路径又十分方便,所以熟练掌握相对路径的使用时一件非常有意义的事。使用相对路径时候一定要注意我上面说的关键点,在遇到具体问题时去套那些原则,一般就能hold住你遇到的所有问题。
网友评论