python全栈闯关--21-模块和包
模块
mymoudle
# -*- coding:utf-8 -*- print('form my_moudle.py') money=1000 def read1(): print("my_moudle read1",money) def read2(): print("my_moudle read2") def change(): global money money = 0
1、使用import导入模块
import sys import my_module import my_module import my_module import my_module print(sys.path) print(sys.modules.keys())
导入模块,会按照当前路径,pytchon解释器的方式去寻找包的路径。
多次导入包,不会重复导入。会根据sys.mmodules里面的值进行判别,包是否已经导入。
money=10 print(m.money) print(money)
包有自己的命名空间,不与当前目录冲突
def read1(): print('this is in main') read1() m.read1()
函数也不与当模块中冲突
m.change() print(money) m.read1()
虽然moudle中,定义了全局变量,但是修改的还是moudle中的值。
导入模块时,第一步,创建模块的命名空间,如果定义了global,引用的依然是命名空间中的模块;
第二部,执行模块中的代码
使用import as 别名来导入模块
导入后,可以使用别名来进行操作,以到达简化代码的目的。
可以通过参数,判断导入不同的参数,简化代码
2、from import
from my_module import read1 def read1(): print('this is in main') money = 10 read1()
本函数中的read1覆盖了导入的read1
from my_module import read1 # def read1(): # print('this is in main') money = 10 read1()
虽然修改了本模块中的money,但是调用的依然是my_module中的值
from my_module import read1 from my_module import read2 def read1(): print('this is in main') # money = 10 # read1() read2()
read2中引用了read1,执行结果使用的money依然是模块中的money
__all__参数
__all__参数与from import * 组合使用,用于过滤导入的数据。只有子all中的函数、变量才会被导入
from my_module import * print(read1) print(read2) print(money) print(change)
没加all参数前,可以导入全部函数、变量
在module中添加all参数后
__all__ = ['read1', 'read2']
```
<function read1 at 0x000001F2D1CBE0D0>
<function read2 at 0x000001F2D1CBE1E0>
print(money)
NameError: name 'money' is not define
```
就只导入了read1和read2
import time,day21.imlib as i import importlib time.sleep(30) importlib.reload(i) i.func1()
如果导入包后,修改了模块,结果不会反应到已经加载的模块中,此时,就需要使用importlib来重新加载包。
如上例子中,如果在休眠的30秒内,修改了imlib,最终执行的不会是罪行的imlib。
使用importlib.reload重新加载后,更新到最新的代码。
包
包导入有两种方式:
一、import
二、from .... import ....
使用import导入,需要录入完整的路径,到模块名,使用时,使用完整的路径名
import glance.cmd.manage as m m.main()
不取别名,会要求整个路径的输入才能使用
from ... import ....
导入的变量,函数可以直接使用
from glance.cmd.manage import * main()
直接使用main()
__init__.py文件
使用import和from ... import ... 时,只导到包名时,会自动加载此文件中的代码
即__init__文件起到一个预效验的作用,导入路径指定到包名,将会按照此文件中的内容进行加载
import glance.api as p p.policy.get() p.func()
在api的__init__.py文件中写入了导入
x=10 def func(): print('this is func from api.__init.py') import glance.api.policy __all__ = ['func','x','policy'] print('from api.__init1111.py')
导入了__init__下的函数变量,也根据文件导入了policy里面的内容
from glance.api import * policy.get() func()
使用from倒入了,到达了和import导入一样的效果,只是调用的方式不同
另外,from和模块一样可以使用__all__参数
__all__ = ['x','policy']
__all__参数,过滤掉了func,此时调用func报错。通一路径下的模块:policy写到了all里面,init中可以不用写导入此模块,也可导入。
相对导入和绝对导入
包中模块使用到其他包里面的内容时,有两种导入方式。
一、绝对导入,使用完整的包名进行导入。
from glance.cmd import manage manage.main() import glance.cmd as m m.manage.main()
二、相对导入
from ..cmd import manage manage.main()
. 代表当前路径,.. 代表父路径
子模块中,互相导入需要杜绝使用import来进行导入。使用from ... import ... 来进行导入。
import一般使用来导入内置模块和三方模块(已经存在于sys.path)中的数据,包子模块中的导入,使用from ... import ...的方式进行导入。
如果绝对路径导入,在包模块中,可以执行代码;
如果使用了相对路径,包子模块中代码将不可运行