执行代码出现ImportError:attempted relative import with no known parent package
前言
在这篇文章中,我将会解析 ImportError: attempted relative import with no known parent package 这个异常的原因。当你在运行的python脚本。使用了相对引用方式 (类似import ..module) 去引用包时,可能会出现这个异常。
让我们来看看发生这个异常的例子。
问题
假设你有以下目录结构:
project
├── config.py
└── demos
├── __init__.py
└── demo.py
config.py 中包含一些应该在 demo.py 中使用的变量
- project/config.py
count = 5
- project/demos/demo.py
from .. import config
print("The value of config.count is {0}".format(config.count))
当我们尝试运行demo.py时,会遇到以下错误:
E:\project> python demos/demo.py
Traceback (most recent call last):
File "demos/demo.py", line 1, in <module>
from .. import config
ImportError: attempted relative import with no known parent package
python解释器抛出了没有父级包的异常。为什么?
让我们看看python解释器是如何解析相关模块。从 PEP 328 中,我们找到了关于 the relative imports(相对引用)的介绍:
Relative imports use a module’s __name__ attribute to determine that module’s position in the package hierarchy. If the module’s name does not contain any package information (e.g. it is set to __main__ ) then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system. 相对导入通过使用模块的 __name__ 属性来确定模块在包层次结构中的位置。如果该模块的名称不包含任何包信息(例如,它被设置为 __main__ ),那么相对引用会认为这个模块就是顶级模块,而不管模块在文件系统上的实际位置。
换句话说,解决模块的算法是基于__name__和__package__变量的值。大部分时候,这些变量不包含任何包信息 —- 比如:当 __name__= __main__ 和 __package__ = None 时,python解释器不知道模块所属的包。在这种情况下,相对引用会认为这个模块就是顶级模块,而不管模块在文件系统上的实际位置。
为了演示这个原理,我们来更新一下代码:
- project/config.py
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
count = 5
- project/package/demo.py
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
from .. import config
print("The value of config.count is {0}".format(config.count))
再次尝试运行一下,会得到以下输出:
E:\project> python demos/demo.py
__file__=demos/demo.py | __name__=__main__ | __package__=None
Traceback (most recent call last):
File "demos/demo.py", line 3, in <module>
from .. import config
ImportError: attempted relative import with no known parent package
正如我们所看到的,python解释器没有关于模块所属的包的任何信息( __name__ = __main__ 和 __package__ = None ),因此它抛出了找不到父级包的异常。
解决方案一
我们通过在其中创建一个新的空
__init__.py文件来将项目目录转换为一个包。我们在项目目录的父目录中创建一个文件
main.py
toplevel
├── main.py
└── project
├── __init__.py
├── config.py
└── demos
├── __init__.py
└── demo.py
- toplevel/main.py
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
import project.demos.demo
执行一下新的示例,输出如下:
E:\toplevel>python main.py
__file__=main.py | __name__=__main__ | __package__=None
__file__=E:\toplevel\project\demos\demo.py | __name__=project.demos.demo | __package__=project.demos
__file__=E:\toplevel\project\config.py | __name__=project.config | __package__=project
The value of config.count is 5
在 main.py 中导入 project.demos.demo 会设置相对引用的包信息( __name__ 和 __package__ 变量)。现在,python解释器可以成功解析 project\demos\demo.py 中的相对引用了。
解决方案二
我们通过在
project文件夹中创建一个新的空__init__.py来将project目录转换为一个包。在
toplevel目录下通过-m参数来调用python解释器,去执行project.demos.demo[1]
toplevel
└── project
├── __init__.py
├── config.py
└── demos
├── __init__.py
└── demo.py
再次执行:
E:\toplevel>python -m project.demos.demo
__file__=E:\toplevel\project\demos\demo.py | __name__=__main__ | __package__=project.demos
__file__=E:\toplevel\project\config.py | __name__=project.config | __package__=project
The value of config.count is 5
运行该命令将自动设置包信息(__package__变量)。现在,python解释器可以成功解析 project\ demos\demo.py 中的相对引用了(甚至认为 __name __ = __ main__ )。
注意使用 -m 参数的时候,后面指定的执行文件没有 .py 后缀。
注2:
实际使用中还有一个可能会报出这种错误, 就是执行代码的路径不对。
E:\toplevel>python -m project.demos.demo
一定要在project的上一级目录执行这个命令。
执行代码出现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
这个问题困扰了我很久了,网上的解决方法都很一致,找来找去都是一样的解决方法,在导入包的文件和执行文件加入 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
problem:Attempted relative import in non-package 所谓相对路径其实就是相对于当前module的路径,但如果直接执行脚本,这个module的name就是“ ...
- 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 in non-package”错误
文章是从stackoverflow翻译过来的,原文地址:Relative imports for the billionth time 本文要在原理上解决 python当中相对包导入出现的问题. 问 ...
- Python 相对导入attempted relative import beyond top-level package
ValueError: attempted relative import beyond top-level package 假设有如下层次包目录 project/ __init__.py mypac ...
- Python ValueError: Attempted relative import in non-package Relative import相对引用 错误
包含相对路径import的python脚本不能直接运行,只能作为module被引用. 例如 from . import mod1 有这样代码的文件只能最为moulule为不能直接运行.相对路径就是相对 ...
- ValueError: attempted relative import beyond top-level package
python 项目 在pycharm中, 在某个文件夹下: 右键--> mark directory as --> source root 如何在python脚本或者shell中 用代码实 ...
随机推荐
- Springboot添加定时任务
请参考这篇文章:https://blog.csdn.net/ysp_0607/article/details/71430281
- java 中根据类的属性排序
package edu.del; import java.util.ArrayList; import java.util.Collections; import java.util.List; im ...
- Python之必备函数
1. lambda 表达式 匿名函数(ANONYMOUS FUNCTION)是指一类无需定义标识符(函数名)的函数.通俗来讲,就是它可以让我们的函数,可以不需要函数名. 正常情况下,我们定义一个函数, ...
- 2018-计算机系机试(第二批)-C-数字字符个数
C. 数字字符个数 单点时限: 1.0 sec 内存限制: 256 MB 输入一行信息,输出其中包含的数字字符个数. 例如:输入 a<4 >w,输出 1 . 输入格式 一行字符串 (可能含 ...
- 3D数学基础(四)四元数和欧拉角
一.四元数 四元数本质上是个高阶复数,可视为复数的扩展,表达式为y=a+bi+cj+dk.在说矩阵旋转的时候提到了它,当然四元数在Unity里面主要作用也在于此.在Unity编辑器中的Transfor ...
- Unity存储路径
一.在项目根目录中创建Resources文件夹来保存文件 可以使用Resources.Load("文件名字,注:不包括文件后缀名");把文件夹中的对象加载出来注:此方可实现对文件实 ...
- SQL注入之Sqli-labs系列第四十一关(基于堆叠注入的盲注)和四十二关四十三关四十四关四十五关
0x1普通测试方式 (1)输入and1=1和and1=2测试,返回错误,证明存在注入 (2)union select联合查询 (3)查询表名 (4)其他 payload: ,( ,( 0x2 堆叠注入 ...
- python 将汉字转换为拼音
xpinyin提供把汉字转为汉语拼音的功能. 安装此模块 pip install xpinyin简单用例: from xpinyin import Pinyin pin = Pinyin() test ...
- blueprint的使用
第一步:导入蓝图模块: from flask import Blueprint 第二步:创建蓝图对象: #Blueprint必须指定两个参数,admin表示蓝图的名称,__name__表示蓝图所在模块 ...
- Python学习之路并发编程--信号量、事件、队列及生产消费模型
1. 信号量 对于多进程来说,多个进程同时修改数据,就可能出现安全隐患,所以引入了锁,这一机制,但锁只能有一把来控制一个的开关,当你需要几把锁的时候,就可能用到信号量的概念.他是用了锁的原理,内置了一 ...