Python:跨文件夹模块调用中的路径问题 您所在的位置:网站首页 c不同文件夹下的函数引用 Python:跨文件夹模块调用中的路径问题

Python:跨文件夹模块调用中的路径问题

2024-07-11 21:35| 来源: 网络整理| 查看: 265

本文介绍Python中跨文件夹调用时,产生的相对路径问题和模块搜索路径问题。 1. 相对路径问题

 假定我们的文件结构如下:

myExperiments -> test_1 -> test_1.py -> img.jpg -> test_2 -> test_2.py

 并且test_1.py中有如下函数,即读取img.jpg文件并返回其是否为None(为None表示读取失败):

import cv2 def read_image(): img = cv2.imread("img.jpg") return img is None # 返回False表示读取图片成功,True则为失败

 我们使用下面的方法在test_2.py中调用该函数,并在PyCharm中运行得到如下结果:

from test_1.test_1 import read_image print(read_image()) [Out]: True

 得到的结果为True,表示我们读取到的图片为None,即图片路径发生了错误。具体地,我们在运行test_2.py时,当前路径是“xxx\myExperiments\test_2”,再加上test_1.py中图片的相对路径“img.jpg",读取图片的路径为”xxx\myExperiments\test_2\img.jpg“,这显然是一个无效的地址。  我们可以在test_1.py和test_2.py中,分别加入下面的代码,来输出该文件夹所对应的路径:(也有人建议os.path.abspath(os.curdir)、os.getcwd()、sys.argv[0],但经过测试还是如下的代码更适用本问题)

import os print(os.path.dirname(__file__))

 加入上述代码后再次运行test_2.py程序,可以打印出两个.py文件的路径:

D:/CV_Project/myExperiments/test_2 D:\CV_Project\myExperiments\test_1 True

 所以,解决办法也就有了,在test_1.py中利用上述代码将相对路径改为绝对路径即可:

test_1,py: def read_image(): img = cv2.imread(os.path.dirname(__file__) + "/img.jpg") return img is None [Out]: False  问题1解决! 2. 模块搜索路径问题

 上述代码在PyCharm中运行得不错,但是当我们在控制台中运行时,会出现模块调用的错误: 在这里插入图片描述  问题产生的原因是,在模块搜索路径中没有找到test_1/test_1.py模块。我们在test_2.py中加入如下代码,并分别在PyCharm和Console中运行,得到如下结果:

test_2.py import sys pprint(sys.path) from test_1.test_1 import read_image print(read_image()) [PyCharm Out]: ['D:\\CV_Project\\myExperiments\\test_2', 'D:\\CV_Project\\myExperiments', 'E:\\Python\\PyCharm 2019.2.5\\helpers\\pycharm_display', 'E:\\Anaconda\\anaconda\\python37.zip', 'E:\\Anaconda\\anaconda\\DLLs', 'E:\\Anaconda\\anaconda\\lib', 'E:\\Anaconda\\anaconda', 'E:\\Anaconda\\anaconda\\lib\\site-packages', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pdfparanoia-0.0.16-py3.7.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pycocotools-2.0-py3.7-win-amd64.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pyqt5_stylesheets-2.3.0-py3.7.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\win32', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\win32\\lib', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\Pythonwin', 'E:\\Python\\PyCharm 2019.2.5\\helpers\\pycharm_matplotlib_backend'] False [Console Out]: ['D:\\CV_Project\\myExperiments\\test_2', 'E:\\Anaconda\\anaconda\\python37.zip', 'E:\\Anaconda\\anaconda\\DLLs', 'E:\\Anaconda\\anaconda\\lib', 'E:\\Anaconda\\anaconda', 'E:\\Anaconda\\anaconda\\lib\\site-packages', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pdfparanoia-0.0.16-py3.7.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pycocotools-2.0-py3.7-win-amd64.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pyqt5_stylesheets-2.3.0-py3.7.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\win32', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\win32\\lib', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\Pythonwin'] Traceback (most recent call last): File "test_2/test_2.py", line 16, in from test_1.test_1 import read_image ModuleNotFoundError: No module named 'test_1'

 这里我们输出的sys.path是指定用于模块搜索路径的字符串列表(module search path; path[0] is the script directory, else ‘’)。我们可以看到,在PyCharm中的sys.path比Console多个’D:\CV_Project\myExperiments’,而test_1/test_1.py模块正是位于该路径下。也正是因此,PyCharm中依据此路径可以成功加载test_1模块,而在Console中不行。  PyCharm这种设置是可以在 “File | Settings | Build, Execution, Deployment | Console | Python Console”中修改的: 在这里插入图片描述  所以,解决这种问题的最直观的方法就是在sys.path中手动添加所需路径,本问题中将test_2.py代码按如下修改:

import os, sys sys.path.insert(0, os.path.abspath( os.path.join( os.path.dirname(__file__), "../")) ) print(sys.path) from test_1.test_1 import read_image print(read_image()) [Console Out]: ['D:\\CV_Project\\myExperiments', 'D:\\CV_Project\\myExperiments\\test_2', 'E:\\Anaconda\\anaconda\\python37.zip', 'E:\\Anaconda\\anaconda\\DLLs', 'E:\\Anaconda\\anaconda\\lib', 'E:\\Anaconda\\anaconda', 'E:\\Anaconda\\anaconda\\lib\\site-packages', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pdfparanoia-0.0.16-py3.7.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pycocotools-2.0-py3.7-win-amd64.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pyqt5_stylesheets-2.3.0-py3.7.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\win32', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\win32\\lib', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\Pythonwin'] False

 这里sys.path.insert(0, xxx)是将’D:\CV_Project\myExperiments’路径插入到sys.path最前面,当然也可以使用os.path.append(xxx)将其插入到最后面。可以看到,采用这种方法后,在Console运行时的sys.path中加入了所需路径,并成功运行。  当然,对于本场景,还有一种更简单有效的方法。“python -m 模块” 的方式是把模块直接当脚本来运行,此时自动把输入命令的目录加入到了sys.path中(而不把.py文件的路径加进去)。所以,我们保持test_2.py为如下内容,并在Console中用python -m 调用:

test_2.py import sys print(sys.path) from test_1.test_1 import read_image print(read_image()) [Console In]: D:\CV_Project\myExperiments>python -m test_2.test_2 [Console Out]: ['D:\\CV_Project\\myExperiments', 'E:\\Anaconda\\anaconda\\python37.zip', 'E:\\Anaconda\\anaconda\\DLLs', 'E:\\Anaconda\\anaconda\\lib', 'E:\\Anaconda\\anaconda', 'E:\\Anaconda\\anaconda\\lib\\site-packages', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pdfparanoia-0.0.16-py3.7.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pycocotools-2.0-py3.7-win-amd64.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\pyqt5_stylesheets-2.3.0-py3.7.egg', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\win32', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\win32\\lib', 'E:\\Anaconda\\anaconda\\lib\\site-packages\\Pythonwin'] False

 我们可以看到,这里sys.path中自动加入了’D:\CV_Project\myExperiments’(而非’D:\CV_Project\myExperiments\test_2’)。注意这个路径是输入命令的地址,当我们改变输入命令的地址时,这个也会发生改变。

 问题2解决! 综上,我们介绍了跨文件夹模块调用时产生的两个路径问题。对于相对路径问题,提出了修改相对路径为绝对路径的解决方法;对于模块搜索路径问题,针对sys.path提出了两种解决方法。 欢迎交流!


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有