一.模块(Module)和包(Package)
1.模块:一个包含所有你定义的函数和变量的文件,其后缀名是 .py ,一个.py文件就是一个模块
2.包:一定包含 __init__.py模块 的文件夹,一般也会包含其他一些模块和子包
3.库(lib):库是完成一定功能的代码集合,具体表现可以是包,也可以是一个模块
4.框架(framework):为解决一个开放性问题而设计的具有一定约束性的支撑结构
5.python内置了一些库,除此之外,还有其他人自己做的一些库,称之为第三方库
6.一般把第三方库放在.../python3/lib/site_packages中
二.第三方库的下载和安装
1.安装第三方库实质上是下载并使用别人写的代码
2.常见的第三方库的格式:源码(Source)(压缩包,需先解压,得到包含setup.py文件夹);egg(本质是压缩包);whl(本质也是压缩文件)
3.安装方式:
(1)源码安装(本地安装):手动下载,再安装到本地;
(2)包管理安装(远程安装):通过命令使自动化的为用户安装管理包和模块
4.源码安装
(1)到对应库托管网站下载所需要的文件,https://pypi.org/或https://www.lfd.uci.edu/~gohlke/pythonlibs/等
(2)下载的文件要对应自己python的版本,还要选择32位还是64位安装的python的系统
(3)打开命令行(win+R cmd):切换到下载的文件所在的目录 cd /d
(4)对于带setup.py的文件(源码文件),输入命令:python setup.py install
注意:若没有setuptools包,需手动下载安装,再利用setuptools安装其他使用setuptools打包的包
(5)对于 .egg文件使用easy_stall安装,输入命令:easy_install xxx.egg(完整文件名称)
(6)对于whl文件可以使用easy_stall如上安装,也可以使用pip安装,输入命令:pip install xxx.whl(完整文件名称)
5.远程安装easy_install和pip,需先知道要安装的库名
6.easy_install:http://peak.telecommunity.com/DevCenter/EasyInstall
(1)是setuptools的自带安装脚本,用于安装.egg文件
(2)在多个python版本的切换安装:安装到3.6python中:easy_install-3.6 xxx
(3)安装指定版本包:easy_install “ 库名 限定符(<,>,<=,>=,==) 版本 ”; 例:easy_install “ request >1.0,<2.0 ” 安装大于1.0并且小于2.0的版本
(4)升级三方包:easy_install --upgrade (-U) 库名,例如:easy_install --upgrade requests
(5)卸载三方包:(1)手动卸载删除对应的包记录或删除在easy-install.pth中的包记录(2)easy_install -m 包名称:自动删除在easy-install.pth中的包记录
(6)-m的真正含义:支持多版本,可在运行时进行切换,使用:>>>import pkg_resources >>>pkg resources.require("对应版本的包名")>>import 对应版本的包
(7)easy_install.pth文件:记录当前通过easy_install已经安装的模块(多个版本的模块,只记录最后一次安装的);用于导入模块时的路径检索
(8)切换三方安装源:在easy_install修改文件setuptoolscommandeasy_install.py文件中搜索pypi.python.org找到对应地址并修改
7.pip:http://pip.pypa.io/en/stable/
(1)是pip库中的安装脚本,用于安装.whl文件
(2)切换安装包安装源:
一次性修改:pip install --index -url https://..../包名(指定检索)或pip install -extra-index-url https://..../包名(拓展检索)
永久性修改
(3)安装在不同的python版本环境中(1)python m pip install xxx或python3 m pip install xxx(2)py -2 m pip install xxx或py -3 m pip install xxx
(4)查看包:已经安装好的包:pip list;不被依赖的包:pip list --not-required ;过期的包:pip list --outdated;某个包的具体信息:pip show xxx
(5)搜索包:pip search xxx或pip search -i 检索地址 xxx
(6)安装指定版本包:pip install “库名 限定符(<,>,<=,>=,==) 版本”; 例:pip install “request >1.0,<2.0”安装大于1.0并且小于2.0的版本
(7)升级三方包:pip install --upgrade (-U) 库名,例如:pip install --upgrade requests注:pip的升级是先卸载当前版本,在下载安装最新版本,如果库存在,直接执行安装命令并不会更新库
(8)卸载三方包:pip uninstall xxx
(9)生成冻结需求的文本:把当前安装的三方包记录存储在指定的文件当中:pip freeze > C:Users11373Desktopao.txt生成存储包信息的文本文档
pip install -r bao.txt下载并安装文本文档中的包
8.pycharm中安装:Settings---project ---project interpreter---界面右边列出不同环境下的包,右边操作:+增加 -删除 |更新----对应的包install package----manage repositories(管理库的链接地址)
9.总结
安装一个库:
(1)pycharm中搜索安装
(2)命令行 pip install xxx
(3)如果上面都出现问题,https://www.lfd.uci.edu/~gohlke/pythonlibs/下载相应库到本地,命令行 pip install xxx.whl
三.导入模块和包
1.使用(from A )import B (as C) 的形式进行导入:从A导入B到当前位置,使用别名C。
(1)from 包 import 单个或多个模块
(2)from 模块 import 模块资源(比如:函数,属性等)
(3)要保证面向原则,即只能导入自己的下一级,不能从包中导入模块的资源或从大包中导入小包的模块
(4)import * 表示导入能匹配到的所有资源,存放在__all__=[ ](列表中每个元素都是字符串)
(5)import和from...import...不存在哪种更省内存,都创建了模块对象,区别在于把哪一部分内容拿到当前位置来用
(6)导入包时如果只写包名,默认不会导入所有模块,应在init模块中再次导入需要的模块或以from...import...的形式导入
2.导入时,需要把命令放在脚本的顶端
3.对同一库的导入只会被执行一次,不管你有多少个import。这样可以防止库被一遍又一遍地执行
4.导入模块时,会自动执行该模块;导入包时,会自动执行对应的init.py文件
5.执行import语句时会自动搜索,来确定该包或模块存在
(1)查找路径顺序是:内存中已经加载的模块 -> 内置模块 -> sys.path路径(导入模块的环境变量)中包含的模块
(2)当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入
(3)当安装第三方模块的时候,如果不是按照标准方式安装,则为了能够引用(import)这些模块,必须将这些模块的安装路径添加到sys.path中
(4)只要包或模块放在sys.path路径中,都可以import使用它
6.第一次导入和第二次导入
(1)第一次导入:在自己当下的命名空间执行所有代码,创建一个模块对象,并将模块内所有顶级变量以属性的形式绑定在模块对象上,在import的位置,引入import后面的变量名称到当前命名空间;第二次导入时,直接执行上述最后一步
按照模块检索路径先后顺序查找:1.内置模块 2.sys.path 3.自己追加路径
(2)追加路径的方式:1.sys.path.append()只限本次添加路径; 2.修改环境变量,仅仅在shell中有效; 3.添加.pth文件
1 import site
2
3 print(site.getsitepackages())#查找特殊路径,可以用来存放.pth文件
4 #在.pth配置文件中添加路径,系统会自动识别
(3)pycharm中修改路径:Settings--Project Interpreters(*的show all)--点击Project Interpreters界面右边的最后一个标识show path---在Interpreter Paths界面中点加号添加路径
(4)sys.path优先级:当前目录---python环境变量中配置的路径----pthon的安装路径-----安装路径下的.pth文件-----lib库(lib\site-packages)----lib库中配置的.pth文件---pycharm我们加的路径
(5)第二次导入:从已经加载过的模块中去找,查看已加载模块:sys.modules
7.导入模块的常见场景:局部导入、覆盖导入(sys中路径前的覆盖路径后的;内置的覆盖自定义的)、循环导入(A导入B,B导入A)、可选导入(两个功能相近的包,根据需求优先选择一个导入try..except...)、包内导入(包外:绝对导入from a import b,包内:相对导入from ../. inport b)
8.当我们尝试去使用解释器去执行某一个py文件的时候,那他就会确定当前文件所在的目录,然后,再把这个目录添加到sys.path。添加过后,再往后,基本上这个sys.path里面的内容已经确定
8.导入模块和导入包
1 #目录:
2 # 导入模块和包---
3 # |
4 # 上级包、上级模块、导入模块和包的init模块-----
5 # |
6 # 同级包、同级模块、上级包的init模块、test模块--------
7 # |
8 # 下级包、下级模块、同级包的init模块-----
9 # |
10 #最下级模块、下级包的init模块
11
12 #以test模块为执行模块导入相应的模块
13 #导入同级模块
14 import 同级模块#直接导入单个模块并执行该模块
15 print(同级模块.name)#打印模块中的name属性
16 print('*'*30)
17
18 #导入下级模块
19 # import 下级模块 #不能直接导入同级包下面的模块No module named '下级模块'
20 # print(下级模块.name)#打印模块中的name属性
21 #修改方法:
22 import 同级包.下级模块#导入同级包的下级模块,执行包的__init__模块和导入的模块
23 print(同级包.下级模块.name)#打印该模块的name属性
24 print('*'*30)
25
26 #导入下下级模块
27 # import 下级包.最下级模块#No module named '下级包'
28 # print(下级包.最下级模块.name)
29 # import 同级包.最下级模块#No module named '同级包.最下级模块'
30 # print(同级包.最级模块.name)
31 #修改:
32 import 同级包.下级包.最下级模块
33 print(同级包.下级包.最下级模块.name)
34 print('*'*30)
35
36 #导入上级模块
37 # import 上级模块#不能直接导入同级包上面的模块No module named '上级模块'’
38 # print(下级模块.name)#打印模块中的name属性
39 #修改方法
40 import 导入模块和包.上级模块#导入再上级包下的上级模块,执行包的__init__模块和导入的模块
41 print(导入模块和包.上级模块.name)
42 ----------------------------------------------
43 执行同级模块
44 同级模块
45 ******************************
46 同级包的init模块
47 执行下级模块
48 下级模块
49 ******************************
50 下级包的init模块
51 执行最下级模块
52 最下级模块
53 ******************************
54 导入模块和包
55 执行上级模块
56 上级模块
1 #导入包
2 import 同级包 #导入同级包直接导入
3
4 # print(同级包.下级模块.name)#module '同级包' has no attribute '下级模块'
5 # 修改:若要使用包下的某个模块,可以在对应init模块中导入相应的模块
6
7 # import 上级包#No module named '上级包'
8 # import 下级包No module named '下级包'
9 #为什么找不到对应的包:因为是在内置模块和sys.path中找,在对应的路径中并没有这个包
10 # 解决:
11 import sys
12 print(sys.path)
13 sys.path.append('E:\python_work\导入模块和包')
14 sys.path.append(r'E:python_work导入模块和包上级包同级包')
15 import 上级包
16 import 下级包
17
18
19 import 导入模块和包
20 ----------------------------------------------------------
21 同级包的init模块
22 ['E:\python_work\导入模块和包\上级包', 'E:\python_work', 'E:\python3.6.4\python36.zip', 'E:\python3.6.4\DLLs', 'E:\python3.6.4\lib', 'E:\python3.6.4', 'C:\Users\11373\AppData\Roaming\Python\Python36\site-packages', 'E:\python3.6.4\lib\site-packages', 'E:\python3.6.4\lib\site-packages\requests-2.18.4-py3.6.egg', 'E:\python3.6.4\lib\site-packages\pymongo-3.6.1-py3.6-win32.egg', 'E:\python3.6.4\lib\site-packages\easygui-0.98.1-py3.6.egg', 'E:\python3.6.4\lib\site-packages\jedi-0.12.0-py3.6.egg', 'E:\python3.6.4\lib\site-packages\parso-0.2.0-py3.6.egg', 'E:\pycharm\PyCharm 2017.3.3\helpers\pycharm_matplotlib_backend']
23 上级包的init模块
24 下级包的init模块
25 导入模块和包
9.导入包
(1)包要想能够使用,__init__.py文件得添加一句from . import * ,意思是从当前包的目录导入所有 模块文件,因为包的导入会首先执行__init__.py
(2) 变量__all__包含一个列表,起到过滤变量、函数和类的作用,表示允许哪些可以被导入
四.sys模块(与系统功能有关的模块)
1.sys.path一个目录列表,供Python从中查找第三方扩展模块
1 import sys
2 #sys.path获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到
3 print(sys.path)
4 -------------------------------------------------------------------------------
5 ['E:\python_work', 'E:\python_work',
6 'E:\python3.6.4\python36.zip',
7 'E:\python3.6.4\DLLs',
8 'E:\python3.6.4\lib',
9 'E:\python3.6.4',
10 'E:\python3.6.4\lib\site-packages',
11 'E:\pycharm\PyCharm 2017.3.3\helpers\pycharm_matplotlib_backend']
2.sys.argv
1 import sys
2 #在外部向程序内部传递参数sys.argv
3 print(sys.argv[0])# 获取脚本名字
4 print(sys.argv)
5
6 for i in sys.argv:
7 print(i) # 获取参数列表
8
9 print(len(sys.argv)-1)# 统计参数个数
10 ------------------------------------
11 E:/python_work/python.3.11.py
12 ['E:/python_work/python.3.11.py']
13 E:/python_work/python.3.11.py
14 0
五.__name__属性
1.a模块被另一个程序第一次引入时,a模块主程序将运行
2.用__name__属性来使程序块仅在模块自身运行时执行,被引用时不执行
3.每个模块都有一个__name__属性,当其值是'__main__'时,表明该模块自身在运行,否则是被引入
4.一个py文件直接以脚本的形式进行执行,它的名字就是__main__;若是使用模块的形式进行加载的,他的名字是由加载的路径决定的:包名.子包名.模块名 顶级名称
1 def dayin():
2 print('dayingg')
3 dayin()
4 if __name__ == '__main__':
5 print('程序自身在运行')
6 else:
7 print('我来自另一模块')
8 ---------------------------------------------------------
9 dayingg
10 程序自身在运行
1 import dayin
2 ---------------------------------------------
3 dayingg
4 我来自另一模块
六.dir() 函数
1.内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回
2.如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称
1 a = [1, 2, 3, 4, 5]
2 import dayin
3 print(dir(dayin))# 得到一个指定模块中定义的名称
4 print(dir()) # 得到一个当前模块中定义的属性列表
5 c=5 # 建立一个新的变量 'a'
6 print(dir())
7 del c # 删除变量名a
8 print(dir())
9 -----------------------------------------------------
10 dayingg
11 我来自另一模块
12 ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'dayin']
13 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'dayin']
14 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'c', 'dayin']
15 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'dayin']
七.补充
1.三方包的版本规则n1.n2.n3
(1)n1:修改了之前的功能或者添加了一个新功能(修改了之前的api)n1+1
(2)n2:新增了某个小功能 n2+1
(3)n3:当版本的bug修复之后 n3+1
2.发布一个包:https://python_packaging.readthedocs.io/en/latest/minimal.html
(1)注册账号pypi
(2)环境准备
(3)发布前的准备
创建一个项目并编译生成发布包;
具体的setup.py脚本文档描述:https://docs.python.org/2/distutils/setupscript.html和https://packaging.python.org/tutorials/distributing-packages/
(打包)命令行执行setup.py:切换包所在目录------python setup.py sdist(自动在包中生成dist文件,里面有压缩好的文件)
readme.rst:http:\zh-sphinx-doc.readthedocs.io/en/latest/contents.html
license.txt:https://choosealicense.com/
manifest.in:https://docs.python.org/3/distutils/sourcedist.html#specifying-the-files-to-distribute
二进制的发行包:解压直接拷贝到指定目录
windows下的安装文件直接双击执行安装
上传到pypi:命令行操作:1.切换目标目录,2.twine upload 要上传的文件