Python中按绝对路径和相对路径导入文件/模块:调试中解决模块找不到问题实例
[id_31496839]id_751692762]

今天调试代码时,程序一直显示没有该模块,这让我很疑惑。因为我导入文件一直是通过绝对路径来进行导入的,按理说是不应该出现模块找不到的情况的。
最后仔细分析了整个代码的目录结构,才发现了问题。
下面依次来说明一下今天的情况
先看导入的代码:
在demo——mnist.py文件中执行以下两种导入操作
# 第一处
from gcforest.gcforest import GCForest
from gcforest.utils.config_utils import load_json
# 第二处
config = load_json("demo_mnist-ca.json") # 里面传入的是文件的位置,这个函数是读取配置文件的内容
然后看一下目录的结构
在此例中,主文件是 demo_mnist.py。它首先要导入的是其当前目录的父目录下的一个子目录中的一个目录里的文件。
所以导入这个文件的方式是以绝对路径进行的,具体为 from lib.gcforest.gcforet import GCForest
从相对路径导入这个文件指的是 from..gcforest.gcforet import GCForest
第二处导入的是它统一个目录下的另一个文件,所以可以直接导入
然后将加载得到的内容赋值给变量 config 。
2、 顺便复习一下相对路径和绝对路径的概念
文件的真正存在路径就是绝对路径。绝对路径是从硬盘的根目录(盘符)开始,然后一级级地进行目录指向,最终指向文件。
相对路径是以当前文件作为基准。它会进行一级级目录的指向。指向的是被引用的资源文件。
以下是常用的表示当前目录和当前目录的父级目录的标识符
../ 表示当前文件所在的目录的上一级目录
./ 表示当前文件所在的目录(可以省略)
/ 表示当前站点的根目录(域名映射的硬盘目录)
在Python中可以验证一下上述的标识方法:
测试的目录结构:
import os
path1=os.path.abspath('.') # 表示当前所处的文件夹的绝对路径
print(path1)
path2=os.path.abspath('..') # 表示当前所处的文件夹上一级文件夹的绝对路径
print(path2)
D 盘下的 PycharmProjects 文件夹中的 mnistCheck 文件夹里有 AbsolutepathAndrelativepath.py 文件。
D:\PycharmProjects\mnistCheck
D:\PycharmProjects
3、 再了解一下Python sys.path的使用
sys.path 是 Python 用于搜索模块的路径集合,它是一个列表,具体如下:
[
'D:\\PycharmProjects\\mnistCheck', 'D:\\PycharmProjects\\mnistCheck', 'D:\\PycharmProjects\\KerasDataSettry', 'C:\\ProgramData\\Anaconda3\\envs\\tensorflow\\python35.zip', 'C:\\ProgramData\\Anaconda3\\envs\\tensorflow\\DLLs', 'C:\\ProgramData\\Anaconda3\\envs\\tensorflow\\lib', 'C:\\ProgramData\\Anaconda3\\envs\\tensorflow', 'C:\\ProgramData\\Anaconda3\\envs\\tensorflow\\lib\\site-packages', 'C:\\ProgramData\\Anaconda3\\envs\\tensorflow\\lib\\site-packages\\Sphinx-1.6.3-py3.5.egg'
]
可以在python 环境下使用: .
sys.path.append(‘你的模块的名称’)。
sys.path.insert(0,’模块的名称’)
添加相关的路径,然而在退出 python 环境之后,自己添加的路径将会自动消失。
代码中的实现如下:
import sys
sys.path.append('C:\Users\Administrator\Desktop\ExperimentAss\gcForest-master')
首先了解一下在不同层级目录中 import 模块的方法(重点),这里主要说的是 python 的相关内容。
有一个名为/home/a 的文件夹,该文件夹里面存在一个模块叫做 b.py,那么我该如何将其导入到程序当中呢?
方法一: (属于刚开始分析的代码里第一种情况)
import sys;
sys.path.append(“/home/a/”)
import b
方法二:
在目录中添加__init__.py 文件,此文件内可以写入在进行 import 操作时执行的代码,同时也可以不写入任何内容而保持为空。
import home.a.b
方法三:
from home.a.b import *
前提是,在 home 和 a 中都包含了__init__.py,也就是说,要导入的文件的当前目录以及其父目录都需要有 init.py 文件。
Python 子目录中的模块方法比较容易,关键在于能在 sys.path 中找到通往模块文件的路径。
下面将具体介绍几种常用情况:
(1)主程序与模块程序在同一目录下:
如下面程序结构:
– src
|– mod1.py
|– test1.py
在程序 test1.py 里导入模块 mod1 时,可以直接使用 import mod1 或者 from mod1 import * 。
(2)主程序所在目录是模块所在目录的父(或祖辈)目录
如下面程序结构:
– src
|– mod1.py
|– mod2
| – mod2.py
– test1.py
若要在程序 test1.py 中导入模块 mod2,那么就需要在 mod2 文件夹中创建一个空文件 __init__.py(也可以在这个文件中自定义输出模块的接口);接着可以使用 from mod2.mod2 import * 或者 import mod2.mod2。
(3)主程序导入上层目录中模块或其他目录(平级)下的模块
如下面程序结构:
– src
|– mod1.py
|– mod2
|– mod2.py
|– sub
| – test2.py
– test1.py
在程序 test2.py 中导入模块 mod1.py 和 mod2.py 时,首先要在 mod2 下创建__init__.py 文件(如同(2)所做的那样),而在 src 下则无需创建该文件。之后的调用方式如下:
下面程序的执行方式都是在程序文件所在的目录下进行。例如,当执行 python test2.py 时,是在执行 cd sub 之后的操作。
test1.py是在执行了“cd src;”之后进行执行的,即执行“python test1.py;”。并且不能保证在 src 目录下执行“python sub/test2.py”能够成功。
import sys
sys.path.append(“..”)
import mod1
import mod2.mod2
从(3)能够得知,导入模块的关键在于能够依据 sys.path 环境变量的值,去找到具体模块的路径。在此仅对上面三种简单情况进行介绍。
总结:
总结后可知,若你要导入的文件与当前文件处于同一个目录,那么你只需直接导入这个文件名即可。
当你的导入文件或目录与当前文件不在同一目录时,你需跳转到要导入文件的父级目录,接着用点号依次连接走过的目录或文件。至于如何跳到父级目录,较为通用的方法是将父级目录添加到系统路径,然后用点号逐级寻找,直至到达要导入的模块。