这是我写的第一遍博客,晚上6点52,有点困,大概写一下。
一、包(Package)、模块(Modules)、脚本(Script)
搞清楚什么是包、什么是模块、什么是脚本很重要,简单来说:
- Script 是用来运行的,也就是
"__name__" == "__main__"
成立的.py
文件 - Modules 是一大堆
Class
funtion
的合集,我们不希望它的"__name__" == "__main__"
成立 - Package 是 Modules 的合集,可以有复杂的文件层级目录。一般而言(老版本的python是强制的)加上
__init__.py
可以被视为是一个包。
二、Import 相对导入的初衷
这个可以从官网的tutorial可以得见。看官们请注意,下图中的.py
文件是不是都是 Module 模块?
这就说明相对导入的目的是为了让模块之间产生关系。
如果试图在Module上运行的时候,已经违背了他的初衷。(应该是Script的作用不是吗?)
三、失败案例
理解了初衷就不难发现,下面这串代码罔顾初衷,试图让不在同一个Package内的两个文件用相对导入发生关系,注定是失败的。(注意,baseline是最大的包,跳出这个文件就是包之外了,project不能成为baseline的parent包,因为train.ipynb作为一个脚本不是包的一部分,所以project文件不是包)
project/
|-- baselines/
| |-- ViT/
| |-- ViT_LRP
|-- src/
|-- train.ipynb
|-- __init__.py
在如图所示的层级结构上,在train.ipynb
上面输入from ..baselines.ViT.ViT_LRP import FGM
,会显示ImportError: attempted relative import with no known parent package
四、成功案例
project/
|-- pkg.py
|-- A
| |-- A1.py
|-- B
|-- B1.py
|-- B2.py
|-- C_test.py
其中,B1.py
如下,
from .B2 import B2_f
from ..A.A1 import A1_f
def B1_f():
print("hello, this is B1")
直接运行B1.py
后,报错(两个都无法导入):
ImportError: attempted relative import with no known parent package
但是用C_test.py
完美运行(均成功导入):
>> from B.B1 import B2_f,A1_f
>> A1_f()
Output: hello, this is A1
五、拓展
本文在表面上粗略介绍了import相对导入遇到的问题,总之包就是包,脚本是脚本。如果用脚本还是建议用绝对路径 Import。
如果想从深入的角度了解背后的原因,可以参考B站某UP讲解,醍醐灌顶。
标签:总结,__,--,py,导入,B1,import,Import From: https://www.cnblogs.com/sq-feng/p/18050602