python模块
就是python文件,里面定义了很多函数,类,变量
模块的作用:
在python交互式解释器中操作输入的代码,在退出python时是不会被保存的; 而模块文件中的代码是永久存在的。
减少重复代码, 减少工作量(写的量、改的量)、代码更优雅、拿来主义
模块的分类
标准模块(库) 无需安装,python自带
import random
第三方模块 需要安装
pip install requests
import requests
自定义模块 自己写的python文件
模块的运行有两种方式:
直接运行
python main.py
导入运行
import main
pyc文件
python2中,模块导入运行的时候会在同级目录下创建一个pyc文件
[root@lier import-test]# ls
first.py second.py
[root@lier import-test]# python2 first.py
this is second
this is first
[root@lier import-test]# ls
first.py second.py second.pyc
python3中,模块导入运行的时候会在同级目录下创建一个__pycache__
文件夹,pyc文件就放在这里
[root@lier import-test]# python3 first.py
this is second
this is first
[root@lier import-test]# ls
first.py __pycache__ second.py
python的执行过程
1、语法分析
2、编译成字节码(.pyc文件)
3、对字节码编译成二进制
但是直接运行的模块不会将字节码保存
导入运行的模块,会将编译好的字节码保存在磁盘上以.pyc结尾
如果没有改动字节码,下次再进行导入运行的时候,就直接查看字节码文件即可,不需要再重新编译成字节码
如果改动了模块,下次运行字节码会重新编译
模块的导入的方式
1、直接导入
import string
print(string.digits)
# 0123456789
2、从模块里面导入函数或者变量/从包是导入模块
from string import digits
print(digits)
# 0123456789
导入两次模块时,只执行一次
第一次导入的时候,就会将这个模块加载到内存空间
下一次导入的时候,会查看内存空间有没有,有的话就直接拷贝过来
先从包中导入模块,再调用模块中的函数
from pack01 import one
from pack01 import one
# this is pack01.one
one.packtest()
# this is pack01.packtest
from pack01.one import packtest
# this is pack01.one
packtest()
# this is pack01.packtest
从模块中导入函数,直接调用函数
当导入的名称一样时,使用后导入的模块
from pack01.one import packtest
from pack02.one import packtest
packtest()
# this is pack02.packtest
导入名称一样时可以使用as起别名
from pack01.one import packtest as pack01test
from pack02.one import packtest
pack01test()
# this is pack01.packtest
packtest()
# this is pack02.packtest
3、导入所有函数
# 导入string模块里的所有东西
from string import *
print(digits)
# 0123456789
4、动态导入
import importlib
# 动态导入string模块
st = importlib.import_module("string")
print(st.digits)
# 0123456789
练习:
接受从键盘的输入,实现动态导入模块
可以无限制导入,按q退出
导入模块之后,输出相应的模块属性dir(),提示相应模块导入成功
while 1:
mod = input("请输入你想导入的模块:")
if mod.lower() == 'q':
break
module = importlib.import_module(mod)
print(dir(module))
print(f"{mod}模块导入成功")
模块的查找
import sys
# 查看当前这个程序里面已经加载好的模块
print(sys.modules)
当导入一个模块时,会先去内存中查找是否已经导入
如果命名空间里面有,则可以直接拷贝到当前的命名空间;
如果没有,就按照sys.path
指定的路径去一个个查找,找不到就报错
print(sys.path)
"""
['E:\\scpythonProject\\2022_4_30_模块与包\\01.模块导入', 'E:\\scpythonProject', 'D:\\Program Files (x86)\\jetbrains toolbox\\apps\\PyCharm-P\\ch-0\\213.6777.50\\plugins\\python\\helpers\\pycharm_display', 'D:\\anaconda3\\envs\\python3.7\\python37.zip', 'D:\\anaconda3\\envs\\python3.7\\DLLs', 'D:\\anaconda3\\envs\\python3.7\\lib', 'D:\\anaconda3\\envs\\python3.7', 'D:\\anaconda3\\envs\\python3.7\\lib\\site-packages', 'D:\\Program Files (x86)\\jetbrains toolbox\\apps\\PyCharm-P\\ch-0\\213.6777.50\\plugins\\python\\helpers\\pycharm_matplotlib_backend']
"""
导入一个模块时会先在当前工作区间查找
[root@lier python-test]# vim string.py
[root@lier python-test]# cat string.py
print("i am string")
[root@lier python-test]# python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/lib64/python36.zip', '/usr/lib64/python3.6', '/usr/lib64/python3.6/lib-dynload', '/usr/local/lib64/python3.6/site-packages', '/usr/local/lib/python3.6/site-packages', '/usr/lib64/python3.6/site-packages', '/usr/lib/python3.6/site-packages'] # 第一个空表示当前工作区间
>>> import string # 当前工作区间创建了一个同名模块string,所以会导入当前空间的模块
i am string
模块和包名要尽量和内置的模块名不相同, 不然会覆盖内置的模块
内置变量__name__
[root@lier import_test]# cat one.py
print("i am one.py")
print(f"__name__的值为:{__name__}")
def add(a, b):
return a+b
if __name__ == "__main__":
print("执行add函数")
print(add(1,2))
当模块直接运行时,它的值就是__main__
[root@lier import_test]# python3 one.py
i am one.py
__name__的值为:__main__
执行add函数
3
当模块导入运行时,它的值就是模块的绝对路径
[root@lier import_test]# ls
first.py one.py __pycache__ second.py
[root@lier import_test]# pwd
/python-test/import_test
[root@lier import_test]# python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import one
i am one.py
__name__的值为:one
[root@lier import_test]# cd ..
[root@lier python-test]# ls
import_test __pycache__ string.py
[root@lier python-test]# pwd
/python-test
[root@lier python-test]# python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from import_test import one
i am one.py
__name__的值为:import_test.one
python包
实际上就是一个目录
包的结构目录里面可以有一个__init__.py
模块
python2 vs python3
python2:__init__.py 必须的
python3:__init__.py 可选的
python2中定义一个python包,里面必须要有__init__.py模块
python3中可有可无