南宁网站制作设计东莞寮步镇网站

当前位置: 首页 > news >正文

南宁网站制作设计,东莞寮步镇网站,视觉营销网站建设规划分析,高考评卷工作全面展开原文链接#xff1a; https://www.cnblogs.com/hi3254014978/p/15317976.html 根据编程经验的不同#xff0c;我们在运行程序时可能经常或者偶尔碰到下面这些问题#xff0c;仔细观察后会发现这些问题无一例外都出现了一个相同的短语#xff0c;很容易就可以发现#xff0…原文链接 https://www.cnblogs.com/hi3254014978/p/15317976.html 根据编程经验的不同我们在运行程序时可能经常或者偶尔碰到下面这些问题仔细观察后会发现这些问题无一例外都出现了一个相同的短语很容易就可以发现这个短语就是relative import。 ValueError: attempted relative import beyond top-level package

翻译试图在顶级包之外进行相对导入ImportError: attempted relative import with no known parent package

翻译尝试相对导入但没有已知的父包ValueError: Attempted relative import in non-package

翻译试图在非包中进行相对导入SystemError: Parent module not loaded, cannot perform relative import

翻译父模块xxx未加载不能执行相对导入。既然关于相对导入的报错提示说明我们在代码中一定用到了相对导入的语法。下面先简单介绍一下相对导入的概念随后详细介绍相对导入可能的问题和原理最后给出上面提到的每个报错的解决方案。 绝对导入 既然要介绍相对导入那必然绕不开绝对导入。绝对导入的格式为 import A.B 或 from A import B 下面是绝对导入的一些 import fibo # 隐式相对导入

from fibo import fibo1, fibo2 # 绝对路径导入 import fibo as fib # 重命名 from fibo import fib as fibonacci相对导入 相对导入格式为 from .A import B 或 from ..X import Y . 代表当前包 .. 代表上层包 … 代表上上层包依次类推。 相对导入的一些案例如下所示 from . import echo # 表示从当前文件所在package导入echo这个module from .. import formats # 表示从当前文件所在package的上层package导入formats这个子package或者moudle from ..filters import equalizer # 表示从当前文件所在package的上层package导入的filters这个子package或者子module中导入equalizer相对导入基于当前模块的名称。由于主模块的名称始终为main因此用作 Python 应用程序主模块的模块必须始终使用绝对导入。主模块所在文件夹不会被视作package因此除了主模块外与主模块处在同个文件夹的模块也就是同级的模块也必须使用绝对导入。 还有个更专业的说法 相对导入使用模块的名称属性来决定模块在包层次结构中的位置如果模块的名称不包含任何包信息例如模块名称为main那么相对导入则被解析为最顶层的位置不管这个时候这个模块实际上位于文件系统中的什么位置。 乍一看是不是觉得云里雾里感觉每个字都认识但就是不知道是什么意思没关系看完本文就理解了。加油。 包package 文件夹被python解释器视作package需要满足两个条件 1、文件夹中必须有init.py文件该文件可以为空但必须存在该文件。 2、不能作为顶层模块来执行该文件夹中的py文件即不能作为主函数的入口。顶层模块即是我们通常说的main方法所在的模块及其同级模块其中main也常被称为主模块即主模块所在文件夹不会被视作package。主模块的同级package被python解释器视为顶级包也就是top-level package。 如果想要导入顶层包更上层的包或者模块需要将包路径添加到sys.path中 第一点很容易理解下面详细介绍一下第二点。 脚本 模块script vs module python有两种加载文件的方法一种是作为顶层的脚本另一种是当做模块。如果你直接执行这个程序那么这个文件就被当做是顶层脚本来执行了在命令行里面输入 python myfile.py 就是这个情况。如果你输入python -m myfile.py或者在其他的文件当中使用import来导入这个文件的时候它就被当做模块来导入。在同一时间里只有一个主模块主模块常被称为顶层脚本顶层脚本可以这样解释它是一个能够让你的程序从这里开始的python文件。 将模块作为脚本执行 test_script.py # test_script.py def fun1(): print(Im fun1)def fun2(): print(“I’m fun2”) if name “main”: fun1() fun2()
脚本中的mainname下的代码仅在模块作为“主”文件执行时才运行 $ python test_script.py Im fun1 Im fun2如果module是作为导入的模块则不会执行该模块的main代码 import fibo这通常用于为模块提供方便的用户界面或用于测试目的将模块作为脚本执行测试套件运行。 模块的名称 当一个文件被加载进来它就有一个名称这个名称存储在name属性当中。如果这个文件被当做一个主模块来执行那么它的名字就是main。如果它被当做一个模块加载那么它的名称就是文件名称加上它所在的包名以及所有的顶层的包名这些名称中间是用点号隔开的。 比如下面的例子 package/ init.pysubpackage1/init.pymoduleX.pymoduleA.py 比如你导入moduleXfrom package.subpackag1 import moduleX它的名称就package.subpackage1.mouleX。如果你导入moduleA的时候from package import moduleA它的名称就是package.moudleA。 注这里是使用包导入,即把package以及里面的所有文件看做一个包导入的时候使用from xxx import yyy的形式来进行我们调用第三方包的时候就是这种情况 但是当你直接从命令行里面运行moduleX的时候他的名称则被替换为main。如果你直接从命令行运行moduleA它的名称也是main。当一个模块被当做一个顶层脚本来执行的时候它原来的名称则会被main取代。 结论 当一个模块的名称中没有包也就是只有文件名的时候说明这个模块是一个顶层模块。顶层模块中不能使用相对导入。相对导入使用模块的名称属性来决定模块在包层次结构中的位置相对导入能向上相对多少级完全取决于模块名称中有多少层。 当你运行交互式的解释器的时候交互式进程的名称永远是main因此你不能在交互式进程当中使用相对导入。相对导入只能在模块文件当中使用。 参考 python相对包导入报“Attempted relative import in non-package”错误 解决方案 1、ImportError: attempted relative import with no known parent package 导致这个问题的原因 主模块或者同级模块用到了相对导入且引用了主模块所在包。因为主模块所在包不会被python解释器视为package在python解释器看来主模块所在的包就是一个未知的父包所以如果不小心以相对导入的方式引用到了就会报with no known parent package这个错误。 案例一 主模块的同级模块在使用相对导入时引入了主模块所在包的案例 TestModule/├── init.py # 这个文件其实未起作用├── main.py # import brother1; print(name)├── brother1.py # from . import brother2; print(name)└── brother2.py # print(name)运行main.py运行结果如下 Traceback (most recent call last):File /TestModule/main.py, line 1, in moduleimport brother1File /TestModule/brother1.py, line 1, in modulefrom . import brother2 ImportError: attempted relative import with no known parent package案例二 主模块在使用相对导入时引入了主模块所在包的案例 TestModule/├── init.py # 这个文件其实未起作用├── main.py # from . import brother1; print(name)├── brother1.py # import brother2; print(name)└── brother2.py # print(name)运行main.py运行结果如下 Traceback (most recent call last):File /TestModule/main.py, line 1, in modulefrom . import brother1 ImportError: attempted relative import with no known parent package方案一 解决方案也很简单将相对导入给成绝对导入即可上面这个案例只需要把from .去掉即可。比如第一个案例 TestModule/├── init.py # 这个文件其实未起作用├── main.py # import brother1; print(name)├── brother1.py # import brother2; print(name)└── brother2.py # print(name)运行main.py brother2 brother1 main方案二 案例2只能使用改为绝对导入这种方式但是案例一还有一种解决方式是把main.py文件移动到TestModule文件夹外面使之与TestModule文件夹平级这样TestModule即会被解析器视为一个package在其他模块中使用相对导入的方式引用到了也不会报错。 2、ValueError: attempted relative import beyond top-level package 导致这个问题的原因 主模块所在同级包的子模块在使用相对导入时引用了主模块所在包。因为主模块所在包不会被python解释器视为package主模块的同级package被视为顶级包也就是top-level package所以主模块所在包其实是在python解释器解析到的顶层包之外的如果不小心以相对导入的方式引用到了就会报beyond top-level package这个错误。 一个案例 TestModule/├── main.py # from Tom import tom; print(name)├── init.py├── Tom│ ├── init.py # print(name)│ ├── tom.py # from . import tom_brother; from ..Kate import kate; print(name)│ └── tom_brother.py # print(name) └── Kate ├── init.py # print(name)└── kate.py # print(name)python main.py Tom # 这个是Tom包的init.py的模块名可以看出包里的init.py的模块名就是包名 Tom.tom_brother Traceback (most recent call last):File /TestModule/main.py, line 1, in modulefrom Tom import tomFile /TestModule/Tom/tom.py, line 2, in modulefrom ..Kate import kate ImportError: attempted relative import beyond top-level package这个问题同样有两个解决方案 方案一 把main.py移动到TestModule文件夹外面使之与TestModule平级这样TestModule即会被解析器视为一个package在其他模块中使用相对导入的方式引用到了也不会报错。 src/ ├── main.py # from TestModule.Tom import tom; print(name) └── TestModule/├── init.py # print(name)├── Tom│ ├── init.py # print(name)│ ├── tom.py # from . import tom_brother; from ..Kate import kate; print(name)│ └── tom_brother.py # print(name) └── Kate ├── init.py # print(name)└── kate.py # print(name)运行main.py TestModule TestModule.Tom TestModule.Tom.tom_brother TestModule.Kate TestModule.Kate.kate TestModule.Tom.tom main方案二 tom.py中将TestModule包加入到sys.path变量中并使用绝对导入的方式导入Kate包修改后的tom.py内容如下 from . import tom_brother import os, sys sys.path.append(..) # 等价于 sys.path.append(os.path.dirname(os.path.dirname(file))) from Kate import kate # 改成绝对导入的方式导入Kate print(name)运行结果如下 Tom Tom.tom_brother Kate Kate.kate Tom.tom main关于为什么已经把TestModule加入了包查找路径还需要使用绝对导入来导入Kate的的解释 从上面的运行结果可以看出tom_brother.py的模块名还是Tom.tom_brother模块名并没有因为把TestModule加入了包查找路径就发生改变而相对导入是根据模块名来确定的如果模块名中没有TestModule那还是不能使用相对导入的方式来导入Kate所以必须使用绝对导入的方式来导入Kate包 3、ValueError: Attempted relative import in non-package 4、SystemError: Parent module not loaded, cannot perform relative import 3和4这两个报错的原因是一样的都是把使用了相对导入的module当做主模块而直接运行了即直接运行的脚本中包含了相对导入。但是我按这种方式操作了一下发现无论怎么操作报错提示始终是上面的第一个报错即ImportError: attempted relative import with no known parent package。 后来发现是python 版本的问题 python2在直接运行的脚本中使用相对导入时会报ValueError: Attempted relative import in non-package这个错误 python3.x没测3.x具体是哪个版本到python3.5报错SystemError: Parent module not loaded, cannot perform relative import  python3.6及以上的报错提示是ImportError: attempted relative import with no known parent package。 解决方案是 去除主模块脚本中的相对导入改为绝对导入。 这个问题的复现花我了好大一番功夫找了好多博客都说是主模块中用到了相对导入但是我这么做就是不报这个错而是报第一个错ImportError: attempted relative import with no known parent package最后还是在一些博客中找到了蛛丝马迹并且用docker快速拉取对应区间python版本镜像验证得出结论平时多学点东西还是很有用处的比如docker看似平时用不上关键时刻还是真帮了大忙否则重新在电脑上安装一个python版本估计又得费老大功夫了。 相对导入对于包的优势 既然会引发这么多问题那是不是我们以后就完全不用相对导入了呢。当然不 相对导入相较于绝对导入还是有一些优势的 书写相较于绝对导入简单相对导入可以避免硬编码带来的包维护问题例如我们改了某一层包的名称那么其它模块对于其子包的所有绝对导入就不能用了但是采用相对导入语句的模块就会避免这个问题。 参考 Python 包内的导入问题绝对导入和相对导入 顺便一提 包查找路径是sys.path变量中。sys.path初始状态一般由三部分组成python正在执行的脚本的目录PYTHONPATH路径包的默认安装路径。 自从python2.6模块的名称不在决定使用name属性而是使用packege属性。这就是为什么我避免使用name这么明确的名称来代表一个模块的名称。自从python2.6一个模块的名称是由package.name来确定的如果packege是None的话那么这个名称就是name了 参考 6.模块 Python包的相对导入时出现错误的解决方法、 python相对包导入报“Attempted relative import in non-package”错误 Python 包内的导入问题绝对导入和相对导入 源文python相对导入常见问题和解决方案