Python 引用问题 - ImportError: attempted relative import with no known parent package
问题描述
近日在尝试引用其他文件的代码时,遇到了错误: ImportError: attempted relative import with no known parent package.
问题大致是这样的:我想在 code2.py
中引用 code1.py
的函数,如 from ..folder1.code1 import xxx
,运行 code2.py
时出现错误。
root
├── folder1
│ └── code1.py
├── folder2
│ └── code2.py
└── main.py
太长不看版
如果你要在 code2.py
中引用 code1.py
的函数,那么可以:
- 改变文件结构,考虑在
main.py
中调用,运行main.py
code2.py
中增加root
的位置到搜索路径sys.path.append
, 代码使用from folder1.code1 import xxx
- 用
-m
选项运行:python -m root.folder2.code2
,代码可以使用from folder1.code1 import xxx
或from ..folder1.code1 import xxx
[我认为这是最优解!]
详细解释
如果对导入的概念不是很理解的话,可能会遇到:
- ModuleNotFoundError: No module named 'xxx'
- ImportError: attempted relative import with no known parent package
首先明确两种导入方法:
from xxx import yyy
则是从已知的模块导入- “relative import” 即
from .xxx import yyy
,根据从当前文件的相对路径导入。
第一种方法
具体可参考官方文档 the-module-search-path
仅适用于模块(文件夹)或脚本(文件)存在于搜索路径中,导入时,Python 解释器会首先搜索内置模块,如果没有,则去以下三个位置搜索:
- 当前文件所在目录
- 环境变量
PYTHONPATH
指定的目录 - Python 默认的安装目录
可以查看 sys.path
,显然,当前运行脚本所在的文件夹被放在了搜索路径的首位,因此该文件夹下的所有内容均可被引入。
import sys
print(sys.path)
# ['/.../path-to-this-folder', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/home/thor/.local/lib/python3.10/site-packages', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']
要解决开头提出的问题,即引入其他文件夹下的内容,可以把 root 的位置添加到搜索路径中:(好吧,这样很不优雅……)
import sys
sys.path.join("/path/to/root") # 用绝对路径,需要从根目录开始
sys.path.join("..") # 用相对路径,但是命令行当前位置不能出错
from folder1.code1 import xxx
可以参考这段代码[1]:
if __package__:
from .. import config
else:
sys.path.append(os.dirname(__file__) + '/..')
import config
第二种方法
具体可参考官方文档 packages
需要明确的是,这种方法只适用于 package 内部!
当你把 code2.py
作为脚本运行时,即 python code2.py
,此时 python 并不会认为它属于某一个 package, 即使存在 __init__.py
。可以 print(__package__)
进行验证,作为脚本运行时为 None
,否则则应该为 xxx.yyy
的形式[1:1]。
(网络上有很多地方都说添加 __init__.py
就可以解决问题,但事实是并不会 ,在我的测试中,在本文提到的所有的解决方法中,添加 __init__.py
与否似乎不会带来什么影响。)
因此,开头描述的问题中,要使用相对导入的形式在 code2.py
中引用 code1.py
的代码,必须使用:
python -m root.folder1.code1
- 这里把 root 及其内部当作一个完整的 package,而 package 内的脚本可以使用相对导入互相引用。
- 这里不带
.py
后缀。 - 不可以为
python -m folder1.code1
,此时把 folder1 及其内部当作一个完整的 package, 无法引用到以外的内容,会遇到 ImportError: attempted relative import beyond top-level package
除了命令行调用时进行调整,在脚本中 import 也是一样的道理:
newroot
├── root
│ ├── folder1
│ │ └── code1.py
│ ├── folder2
│ │ └── code2.py
│ └── main.py
└── upper_main.py
- 在
upper_main.py
中添加from root.folder2 import code2
并运行时,它会把root
当作一个包,此时code2.py
中的from ..folder1.code1 import xxx
可以正常执行 - 在
main.py
中添加import folder2.code2
并运行时,它会把folder2
当作一个包,此时code2.py
中的from .xx import
可以正常执行,而from ..folder1.code1 import xxx
会遇到 ImportError: attempted relative import beyond top-level package.
其他
说明:
- 这里仅说明我尝试成功得出的经验,不排除有其他正确做法。
- 我还看到过类似
code2.py
中有from folder1 import code1
这种做法,没有测试过其适用条件,不过模块内部感觉使用相对引用比较好。
其他参考资料:
- python - ImportError: attempted relative import with no known parent package - Stack Overflow
- python - Why pytest always says " ImportError: attempted relative import with no known parent package" - Stack Overflow
Python 引用问题 - ImportError: attempted relative import with no known parent package的更多相关文章
- Python工程:ImportError: attempted relative import with no known parent package
Python工程:ImportError: attempted relative import with no known parent package 解决方法: 1.对每个目录创建的时候都选择创建 ...
- 执行代码出现ImportError:attempted relative import with no known parent package
前言 在这篇文章中,我将会解析 ImportError: attempted relative import with no known parent package 这个异常的原因.当你在运行的py ...
- 执行文件异常报错:ImportError: attempted relative import with no known parent package
这个问题困扰了我很久了,网上的解决方法都很一致,找来找去都是一样的解决方法,在导入包的文件和执行文件加入 1 print('__file__={0:<35} | __name__={1:< ...
- ImportError: attempted relative import with no known parent package
或者检查所导包是否存在__init__.py文件,没有则添加上即可使当前文件夹变为包.
- python相对包导入报“Attempted relative import in non-package”错误
文章是从stackoverflow翻译过来的,原文地址:Relative imports for the billionth time 本文要在原理上解决 python当中相对包导入出现的问题. 问 ...
- Python ValueError: Attempted relative import in non-package Relative import相对引用 错误
包含相对路径import的python脚本不能直接运行,只能作为module被引用. 例如 from . import mod1 有这样代码的文件只能最为moulule为不能直接运行.相对路径就是相对 ...
- python:Attempted relative import in non-package
problem:Attempted relative import in non-package 所谓相对路径其实就是相对于当前module的路径,但如果直接执行脚本,这个module的name就是“ ...
- Python 相对导入attempted relative import beyond top-level package
ValueError: attempted relative import beyond top-level package 假设有如下层次包目录 project/ __init__.py mypac ...
- ValueError: Attempted relative import in non-package
执行:python deom/scripts/populate.py ValueError: Attempted relative import in non-package solve:python ...
- Python导入自定义类时显示错误:attempted relative import beyond top-level package
显示这个错误可能有两个原因: 1.文件夹中没有包含__init__.py文件,该文件可以为空,但必须存在该文件. 2.把该文件当成主函数入口,该文件所在文件夹不能被解释器视作package,所以可能导 ...
随机推荐
- 【FINALE】NOIP2022 退役记 || THE END.
我的停课生活相册 - password:1007 目录 Day -4 Day -2 Day -1 Day 1 2022/11/26 NOIP 2022 OI 浅忆录 Day -4 好冷啊.有了那么点冬 ...
- DolphinDB +Python Airflow 高效实现数据清洗
DolphinDB 作为一款高性能时序数据库,其在实际生产环境中常有数据的清洗.装换以及加载等需求,而对于该如何结构化管理好 ETL 作业,Airflow 提供了一种很好的思路.本篇教程为生产环境中 ...
- Linx 阶段一
Linux Linux常用命令 具体演示 1). ls 2). pwd 3). touch 4). mkdir 5). rm 使用技巧 1. 连按 Tab健自动补齐文件名 2. ll 查看当前目录文件 ...
- P4055 [JSOI2009] 游戏(博弈论 、最大匹配)
P4055 [JSOI2009] 游戏 目录 P4055 [JSOI2009] 游戏 题目传送门 题目大意 : 思路: code 题目传送门 题目大意 : 小AA和小YY玩游戏,在这个游戏中,同一个格 ...
- Typora 隐藏侧边栏图片文件夹
前言 在使用 Typora 的时候,我将图片的保存路径设置为了如下所示: 这样设置是为了更方便的管理笔记中的图片,但图片文件夹却也显示在了侧边栏中,随着笔记增多,我的侧边栏越来越乱... 难道要忍气吞 ...
- 2022CSP游记
目录 CSP-J2022 7:45 8:15 8:27 8:38 9:12 9:23 10:34 11:57 中午 CSP-S2022 2:27 4:15 6:12 估分 普及 提高 自查 出分 废物 ...
- 原来Spring能注入集合和Map的computeIfAbsent是这么好用!
大家好,我是3y,今天继续来聊我的开源项目austin啊,但实际内容更新不多.这文章主是想吹下水,主要聊聊我在更新项目中学到的小技巧. 今天所说的小技巧可能有很多人都会,但肯定也会有跟我一样之前没用过 ...
- Wolai 使用教程:嵌入小组件库,打造精美、强大的知识库主页
Wolai /我来云笔记在 2022.7.11 日的更新中,支持嵌入包括 NotionPet.芦笋.Replit 等在内的第三方应用.感谢 Wolai 云笔记官方对于 NotionPet 的支持. 趁 ...
- 2022-12-27:etcd是无界面的,不好看,joinsunsoft/etcdv3-browser是etcd的web可视化工具之一。请问在k3s中部署,yaml如何写?
2022-12-27:etcd是无界面的,不好看,joinsunsoft/etcdv3-browser是etcd的web可视化工具之一.请问在k3s中部署,yaml如何写? 答案2022-12-27: ...
- 2022-12-03:部门工资最高的员工。以下数据Max 和 Jim 在 IT 部门的工资都是最高的,Henry 在销售部的工资最高。sql语句如何写? 输出结果如下: department emp
2022-12-03:部门工资最高的员工.以下数据Max 和 Jim 在 IT 部门的工资都是最高的,Henry 在销售部的工资最高.sql语句如何写? 输出结果如下: department empl ...