python - 模块与包
目录
1.1什么是模块:
模块就是python文件,里面定义了很多函数,类,变量
一个完整,大型的python程序是由模块和包的形式组织起来的,
可见模块在python中的重要性
python模块就是python文件
1.2模块有什么作用:
在python交互式解释器中输入的代码,在退出python时是不会保存的,而模块文件中的代码是永久存在的
减少重复代码,减少工作量,代码更优雅,拿来主义
1.3 模块与包里面python2和python3的区别
python包实际是一个目录
包结构的目录里面可以有一个_init_.py模块
python2里面 _init_.py是必选的
python3里面_ini_.py是可选的
1.4 python模块分类
标准模块(无需安装和编写,自动导入就有的模块,例如random,math)
第三方模块(别人写好的发布到平台上的模块,需要安装,比如request,需要pip安装)
自定义模块 (自己写的)
##################################
2.1 导入标准模块的几种方式
2.2 直接导入模块
import string
print(string.ascii_uppercase)
ABCDEFGHIJKLMNOPQRSTUVWXYZ
##################################
2.3 ·从模块里面导入
from string import ascii_uppercase
print(string.ascii_uppercase)
ABCDEFGHIJKLMNOPQRSTUVWXYZ
##################################
2.4 模糊导入模块
# 模糊导入
from string import *
print(ascii_lowercase)
##################################
2.5 使用 importlib动态导入模块
import importlib
st = importlib.import_module('string')
print(st.digits)
0123456789
# 接受用户从键盘的输入,按q退出,用户输入什么模块就导入什么模块,并且提示导入成功/失败
# import importlib
# while True:
# choice = input("请输入您要导入的模块:")
# if choice == 'q':
# print("退出成功")
# break
# else:
# st = importlib.import_module(choice)
# print("导入成功!")
##################################
2.6.1 相同模块的导入
同一个模块导入多次,只会执行第一次的
# 一个模块重复导入,只执行第一次
from pack01 import one
from pack01 import one
##################################
2.6.2 怎么实现导入相同模块(取别名)
取别名
from pack01.one import packtest as packtest_01
from pack02.three import packtest
packtest_01()
packtest()
import pandas as pd
pd.to_date()
##################################
2.7 相对导入
以.开头的导入路径称为相对导入 一个.表示当前 两个.代表上级 三个.代表上上级
##################################
3.1 模块查找顺序
导入一个模块,会先查看内存空间有没有加载,加载了的话会直接将模块的内容 1. Python 中所有加载到内存的模块都放在sys.modules 当import一个模块时首先会在 这个列表中查找是否已经加载了此模块, 如果加载了则只是将模块的 名字加入到正在 调用import的模块的Local名字空间中 如果没有加载则从sys.path目录中按照模块名 称查找模块文件 2. 如果都没有找到模块名就报错
sys.path
第一项代表当前目录,会先到当前路径查找模块,如果没有就会按顺序往下找
'/lianxi/lianxi2' 代表当前所在目录
'/usr/lib64/python3.6' 代表linux系统里面python标准模块的存放目录
/usr/lib/python3.6/site-packages' 代表第三方模块存放目录
例如,我在当前目录写一个string.py文件
里面写入
i am string
然后
[root@localhost lianxi2]# vim string.py
[root@localhost lianxi2]# vim mod.py
[root@localhost lianxi2]# cat string.py
print(i am string)
[root@localhost lianxi2]# cat mod.py
import string
[root@localhost lianxi2]# python3 mod.py
i am string
因为会先到当前目录来查找模块,所以会先找到当前目录的string
如果找到了就返回了就不会再往后面路径查找模块了。
所以起模块名的时候,尽量不要和第三方库或者标准库的模块重名
##################################
因为sys.path是以列表存储的路径
所以我们可以将要添加的模块的路径追加进来,这样就可以找到了
使用 sys.path.append来添加

##################################
4.1 python下划线
4.2 __init__.py文件
__init__.py是一个初始化文件
一般要导入当前包里面的内容都会先执行__init__.py文件
在做项目的时候我们可以将一些初始化操作放到里面
例如 初始化数据库连接
__init__.py可有也可以没有

当使用
from code import model
可以看到
a,_a,__a,__a__以及_func()和func()都可以正常执行

##################################
4.2.1 使用模糊导入时候
_a,__a,__a__以及定义的函数都会无法显示、
因为模糊导入的时候,默认是识别不了下划线开头的变量的

模块导入的时候的模糊设置:
当我们使用模糊导入想导入code下面的所有模块的时候
发现只会导入__init__.py

##################################
4.2.2 如何导入所有?
要在__init__.py这里加一个关键变量
__all__ 变量是一个列表,在列表里面有哪些模块,导入的时候就有哪些
将 model.py 和 _model.py都放进__all__变量里面

这样模糊导入的时候就可以了

一般以双下划线开头和以双下划线结尾的变量,函数,类,模块,这些都是由特殊含义的
标识符
__name__是python中的一个特殊内置变量
在model.py文件里面:

在mod.py里面导入运行时候,__name__显示:

在model.py里面直接运行时候__name__显示:

其实在很多地方我们可以看到这样的代码:

当这个模块是直接运行的时候,__name__就是__main__
当这个模块是导入运行的时候,__name__就是当前模块的导入时候的绝对路径
##################################
4.2.3 代码测试
我们可以运用这点来进行代码测试:
例如:
有一个两数相加的函数需要我们验证,就可以用这种方式
只有是模块直接运行的时候会运行这段测试代码

当模块是导入运行的时候,这段测试代码不会运行。

##################################
4.3 __pycache__文件夹
当我们进行模块导入的操作时候,同级目录下面就会有这个目录
将生成的字节码保存在此目录下面,
下一次使用时候会直接运行字节码文件
但是我们在pycharm里面看不到。


里面是什么内容?
当我们进行模块导入操作的时候就会出现__cache__文件夹

python3会生成__pycache__目录
python2只会在模块同级目录下面生成.pyc文件

##################################
5.1 文件与模块执行过程

##################################
5.2 Python文件执行的过程·
1.词法语法检查·
2.在内存中生成PyCodeObject·
3.执行PyCodeObject
Python模块导入执行的过程·
通过sys.path环境变量找到模块文件·编译成字节码文件(pyc文件)·如果字节码过期了会自动重新生成·如果字节码文件已存在则直接导入字节码文件·执行模块中的代码来创建所定义的对象
##################################
5.3 模块打包与发布
当我们写了一个很好的模块,我们怎么分享给别人?
可不可以将我们的模块打包让别人使用pip让别直接install呢?
如何分享模块
如何我们写了一个计算Fab第N项的函数,如何分享给别人呢?
• 拷贝?
• 导入问题?
• 依赖问题?
##################################
5.3.1 打包与安装:
1.准备一个空文件夹pack
2.在pack下面touch一个__init__.py
3.在pack目录下面新建一个setup.py文件
4.运行 python3 setup.py check进行语法检测
running check 说明语法没问题
5.运行python3 setup.py sdist
如果成功的话就会出现一个dist目录,dist目录下面就是我们已经打包好的模块
[root@localhost pack]# ls
dist modpack modtest.egg-info setup.py
[root@localhost pack]# cd dist/
[root@localhost dist]# ls
modtest-0.0.1.tar.gz
6.在自己机器·上面安装我们打包的模块。
[root@localhost dist]# pip3 install modtest-0.0.1.tar.gz
WARNING: Running pip install with root privileges is generally not a good idea. Try pip3 install --user instead.
Processing ./modtest-0.0.1.tar.gz
Collecting xlrd>=1.1.0 (from modtest==0.0.1)
Downloading https://files.pythonhosted.org/packages/a6/0c/c2a72d51fe56e08a08acc85d13013558a2d793028ae7385448a6ccdfae64/xlrd-2.0.1-py2.py3-none-any.whl (96kB)
100% |████████████████████████████████| 102kB 103kB/s
Installing collected packages: xlrd, modtest
Running setup.py install for modtest ... done
Successfully installed modtest-0.0.1 xlrd-2.0.1
7.测试:导入刚才安装的包
[root@localhost dist]# 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 modpack import mod
i am mod.py
>>> mod.func()
this is mod.py function
>>>
浙公网安备 33010602011771号