python使用import引入其他目录文件或自定义模块

您所在的位置:网站首页 python怎么用自定义函数 python使用import引入其他目录文件或自定义模块

python使用import引入其他目录文件或自定义模块

2024-07-02 02:59| 来源: 网络整理| 查看: 265

问题描述

在python工程中,常常需要使用import引入自己编写的其他模块,但其它模块有时不在同一个文件夹下。此时直接import会导致找不到包而报错ModuleNotFoundError: No module named '****'。下面提供2种解决方案。

解决方案

以下面的项目结构为例进行说明。 在这里插入图片描述

# 方案1:使用相对路径(局限)

在import时直接使用相对路径,.代表当前文件所在路径,..代表当前文件的父目录,...代表爷爷目录,以此类推,每多一个点,就向上翻一层目录。

例1,在f1.py中写:

from ..p2 import f2.py

例2,在t1.py中写:

from ..b import t2.py

这样写能否执行成功,取决于主函数入口(即你执行的文件)!记住这个原则(局限):

相对路径所涉及的目录范围内不允许有主函数入口

不满足这个原则时,报错ValueError: attempted relative import beyond top-level package。在上面的项目结构中,如果我们执行python main.py,那么在main.py中引入t1.py会报错,原因是t1.py中使用相对引入时,..回退到的目录是项目主目录,也就是main.py所在的目录,违反了该原则。但在main.py中引入f1.py是正确的,因为f1.py在使用相对路径引入时最多回退到pkg文件夹,不会影响main.py的执行。

# 方案2:绝对路径引入(推荐) 1. 在main.py中调用t1.py

这个很常规,直接在main.py使用import即可

form a.t1 import * 2. 在t1.py中调用main.py

在t1.py中写:

import sys from pathlib import Path sys.path.append(str(Path(__file__).resolve().parents[1])) # 将父级目录加入执行目录列表 from main import * # 由于main.py所在目录已加入到sys.path,可直接引入

代码中parents返回一个列表,parents[0]代表该文件所在目录,下标每加一,目录向上一层,所以这里parents[1]得到的是父目录。

3. 几个坑 1. os.getcwd()

这个函数获取的始终是当前终端所在目录。

例如我的终端现在处在/home/code/下,执行python a/1.py,文件1.py中的语句os.getcwd()返回值为/home/code/。

2. __file__

当前文件相对于终端的路径。

例如我的终端现在处在/home/code/下,执行python a/1.py,文件1.py中的语句__file__返回值为a/1.py。 使用os.path.abspath(__file__)可获得该文件的绝对路径/home/code/a/1.py。

Tips:拼接路径os.getcwd()/__file__就是该文件的完整绝对路径。

3. sys.path[0]

直接运行py文件,即python xxx.py时,为执行文件所在的绝对目录(不管终端处于什么路径)。 需要注意,若执行python 1.py,而1.py中又import了其他目录的2.py,那么2.py的sys.path[0]与1.py中相等,也就是说在import其他文件时,其他文件的sys.path[0]将以当前被执行的文件为准。

以模块运行时,即python -m xxx时,为终端所在绝对目录,等于os.getcwd()。

4. 总结

在.py文件中,使用__file__最保险。

但是在.ipynb文件中不存在__file__变量,怎么办?由于.ipynb文件一般不考虑被其他文件import,因此直接使用sys.path[0]取得文件所在目录即可。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3