6. 模块和包

一. 模块(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,需先知道要安装的库名

常用国内镜像服务器地址:
	https://blog.csdn.net/yamadeee/article/details/80178996
	
安装命令:
	pip install xxxx -i https://pypi.tuna.tsinghua.edu.cn/simple
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修改文件setuptools\command\easy_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:\Users\11373\Desktop\bao.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文件
import site

print(site.getsitepackages())#查找特殊路径,可以用来存放.pth文件
#在.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里面的内容已经确定

9.导入模块和导入包
'''
目录:
 导入模块和包---
   |
 上级包、上级模块、导入模块和包的init模块-----
   |
 同级包、同级模块、上级包的init模块、test模块--------
   |
 下级包、下级模块、同级包的init模块-----
   |
最下级模块、下级包的init模块
'''
#以test模块为执行模块导入相应的模块
#导入同级模块
import 同级模块#直接导入单个模块并执行该模块
print(同级模块.name)#打印模块中的name属性
print('*'*30)

#导入下级模块
# import 下级模块 #不能直接导入同级包下面的模块No module named '下级模块'
# print(下级模块.name)#打印模块中的name属性
#修改方法:
import 同级包.下级模块#导入同级包的下级模块,执行包的__init__模块和导入的模块
print(同级包.下级模块.name)#打印该模块的name属性
print('*'*30)

#导入下下级模块
# import 下级包.最下级模块#No module named '下级包'
# print(下级包.最下级模块.name)
# import 同级包.最下级模块#No module named '同级包.最下级模块'
# print(同级包.最级模块.name)
#修改:
import 同级包.下级包.最下级模块
print(同级包.下级包.最下级模块.name)
print('*'*30)

#导入上级模块
# import 上级模块#不能直接导入同级包上面的模块No module named '上级模块'’
# print(下级模块.name)#打印模块中的name属性
#修改方法
import 导入模块和包.上级模块#导入再上级包下的上级模块,执行包的__init__模块和导入的模块
print(导入模块和包.上级模块.name)
----------------------------------------------
执行同级模块
同级模块
******************************
同级包的init模块
执行下级模块
下级模块
******************************
下级包的init模块
执行最下级模块
最下级模块
******************************
导入模块和包
执行上级模块
上级模块
#导入包
import 同级包 #导入同级包直接导入

# print(同级包.下级模块.name)#module '同级包' has no attribute '下级模块'
# 修改:若要使用包下的某个模块,可以在对应init模块中导入相应的模块

# import 上级包#No module named '上级包'
# import 下级包No module named '下级包'
#为什么找不到对应的包:因为是在内置模块和sys.path中找,在对应的路径中并没有这个包
# 解决:
import sys
print(sys.path)
sys.path.append('E:\\python_work\\导入模块和包')
sys.path.append(r'E:\python_work\导入模块和包\上级包\同级包')
import 上级包
import 下级包


import 导入模块和包
----------------------------------------------------------
同级包的init模块
['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']
上级包的init模块
下级包的init模块
导入模块和包

导入包

四. sys模块(与系统功能有关的模块)

1.sys.path一个目录列表,供Python从中查找第三方扩展模块
import sys
#sys.path获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到
print(sys.path)
-------------------------------------------------------------------------------
['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',
 'E:\\python3.6.4\\lib\\site-packages', 
'E:\\pycharm\\PyCharm 2017.3.3\\helpers\\pycharm_matplotlib_backend']

sys.path
2.sys.argv
import sys
#在外部向程序内部传递参数sys.argv
print(sys.argv[0])# 获取脚本名字
print(sys.argv)

for i in sys.argv:
    print(i)       # 获取参数列表

print(len(sys.argv)-1)# 统计参数个数
------------------------------------
E:/python_work/python.3.11.py
['E:/python_work/python.3.11.py']
E:/python_work/python.3.11.py
0

sys.argv

五. __name__属性

1.a模块被另一个程序第一次引入时,a模块主程序将运行

2.用__name__属性来使程序块仅在模块自身运行时执行,被引用时不执行

3.每个模块都有一个__name__属性,当其值是'__main__'时,表明该模块自身在运行,否则是被引入

4.一个py文件直接以脚本的形式进行执行,它的名字就是__main__;若是使用模块的形式进行加载的,他的名字是由加载的路径
决定的:包名.子包名.模块名    顶级名称
def dayin():
    print('dayingg')
dayin()
if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')
---------------------------------------------------------
dayingg
程序自身在运行

dayin.py
import dayin
---------------------------------------------------------
dayingg
我来自另一模块

六. dir() 函数

1.内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回

2.如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称
a = [1, 2, 3, 4, 5]
import dayin
print(dir(dayin))# 得到一个指定模块中定义的名称
print(dir())     # 得到一个当前模块中定义的属性列表
c=5 # 建立一个新的变量 'a'
print(dir())
del c # 删除变量名a
print(dir())
-----------------------------------------------------
dayingg
我来自另一模块
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__',
 'a', 'dayin']
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', 
'__spec__', 'a', 'dayin']
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', 
'__spec__', 'a', 'c', 'dayin']
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', 
'__spec__', 'a', 'dayin']

dir()

七. 补充

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 要上传的文件

猜你喜欢

转载自blog.csdn.net/qq_21153997/article/details/95043310
今日推荐