21. python __init__.py 文件的行为

重复打印行为分析

    • 说明
    • 结论
    • 主模块
    • 主模块所在位置不会被python认为是包
    • import 绝对路径问题

说明

21. python __init__.py 文件的行为_第1张图片
我在调试代码的时候,发现上面的print打印了两次,如果将图片中的
from aaa.F import Cat 改成 from F import Cat 则print只会打印一次。这是为什么呢?

结论

from aaa.bbb.ccc import *
则用 ‘.’ 分割的每个包中的 init.py 都会执行一次,顺序依次为:aaa->bbb->ccc
这个特性十分重要,一不小心容易重复打印。

主模块

直接运行的文件称为 主模块, 主模块中 以及其同级 模块都不能用相对导入否则报错。例子如下

# 案例一:主模块同级模块使用相对导入
TestModule/

    ├── __init__.py    # 这个文件其实未起作用

    ├── main.py    # import brother1; print(__name__)

    ├── brother1.py # from . import brother2; print(__name__) #同级模块使用了相对导入则一定报错

    └── brother2.py # print(__name__)
案例二:主模块使用相对导入
TestModule/

    ├── __init__.py    # 这个文件其实未起作用

    ├── main.py    # from . import brother1; print(__name__)

    ├── brother1.py # import brother2; print(__name__)

    └── brother2.py # print(__name__)

主模块所在位置不会被python认为是包

TestModule/

    ├── main.py 
    |     from Tom import tom; print(__name__) # 这是主模块 
    ├── __init__.py

    ├── Tom
    │   ├── __init__.py # print(__name__)
    │   ├── tom.py from . import tom_brother; rom ..Kate import kate; print(__name__) ## 相对导入父级包,但是运行main.py时候,父级已经不被视为包了,报错

    │   └── tom_brother.py # print(__name__) 

    └── Kate      

         ├── __init__.py # print(__name__)

         └── kate.py # print(__name__)

当运行main.py的时候,则TestModule会自动失去包的概念,则其他模块有 用相对路径 来导入main.py所在路径下的包时会报错。因为main.py所在位置已经不被识别为包了。

https://zhuanlan.zhihu.com/p/416867942

import 绝对路径问题

21. python __init__.py 文件的行为_第2张图片

如果要在bbb中的__init__.py 中使用aaa中的tudouya.py,则用from aaa import tudouya 报错,但是用from app.aaa import tudouya 不报错
这是因为:

包的导入是基于模块的绝对路径的。
当使用from aaa import tudouya
时,Python会尝试在当前目录下找到aaa模块,但是在当前目录下并没有aaa模块,所以会报错。 而
当使用from app.aaa import tudouya
Python会根据绝对路径去寻找aaa模块,这时就可以成功导入tudouya模块。
因此,要在bbb中的__init__.py 中使用aaa中的tudouya.py,应该使用from app.aaa import tudouya。

你可能感兴趣的:(python,实战记录,python,开发语言)