第二模块第21章模块 包

egon老师知乎文章地址:

https://www.luffycity.com/play/20704

 

1. 什么是包?

包就是一个包含__init__.py文件的文件夹

包的本质是模块的一种形式

2. 为何要有包?

包的本质是模块的一种形式, 包会被当作模块被导入

 

import mm做的三件事:

  1. 产生一个名称空间

  2. 运行包下的__init__.py文件, 将运行过程中产生的名字都丢到名称空间中去

  3. 在当前执行文件的名称空间中拿到一个名字, 该名字指向1的名称空间

 

强调:

  1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

  2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块

 

3. 包的使用

  要想调用到包中的功能, 需要将包中包含的各个py文件导入到__init__.py文件中, 导入方式如下:

  1. 绝对导入(站在包设计者的角度)

  以包的文件夹作为起始进行导入

  示例:

  文件路径:

  

 

包''bb和"执行文件"run包"在同一路径下, 'run包'中可以使用以下代码调用bb包:

# 方式一
import
bb bb.f1() bb.f2()
'''
结果:
这是m1
这是m2
'''
# 方式二
from bb import f1, f2
f1()
f2()
'''
结果:
这是m1
这是m2
'''

如果包bb与执行文件不在同一路径下, 则调用方法如下:

# 方式一
import sys
sys.path.append(r'F:\python全栈开发\python\day21\aa')
import bb
bb.f1()
bb.f2()
'''
结果:
这是m1
这是m2
'''
# 方式二
import sys
sys.path.append(r'F:\python全栈开发\python\day21\aa')
from bb import f1, f2
f1()
f2()
'''
结果:
这是m1
这是m2
'''

 注意: 环境变量是以执行文件为准的, 所有被导入的模块或后续的其他文件引用的sys.path都是参照执行文件的.

强调:

1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包, 模块,函数,类(它们都可以用点的方式调用自己的属性)。

import a.b.c.d.e.f
from a.b.c.d.e.f import xxx
# 以上两种导入方式中, .f左侧的a b c d e都必须是包

例如:

2、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

3、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

 

  2. 相对导入

# 相对导入
# .:代表当前文件夹
# ..:代表上一层文件夹
from .m1 import f1
from .cc.m3 import f3
# from bb.m1 import f1
from ..m1 import f1
def f3():
    print('这是m3')
    f1()

相对导入有非常大的局限性, 仅限于包内模块之间相互引用, 不能跨出包.

绝对导入是没有任何限制的, 绝对导入是一种通用的导入方式.

包内模块之间的导入推荐使用相对导入, 因为如果采用绝对导入的方法, 当后面需要改包的时候, 相应的导入也得改.

不管是绝对导入, 还是相对导入, 都是包的设计者所做的事, 使用者不用考虑.

from bb import *
*表示从bb中导入__init__中的所有名字.

总结: 自己很少会涉及到自定义包, 如果要写大项目, 可能会自定义包. 

posted @ 2020-06-29 11:39  自由者妍  阅读(151)  评论(0)    收藏  举报