Python——第五章:模块(Module)、自定义模块、第3方开源模块、包(Package)
什么是模块(Module)?
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。
为了编写可维护的代码,我们把很多代码按功能分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就可以称之为一个模块(Module)。
使用模块有什么好处?
- 最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
- 使用模块还可以避免函数名和变量名冲突。每个模块有独立的命名空间,因此相同名字的函数和变量完全可以分别存在不同的模块中,所以,我们自己在编写模块时,不必考虑名字会与其他模块冲突
模块的三种分类,具体如下:
-
内置标准模块(标准库): 这是Python语言自带的模块,你可以在Python的官方文档中找到这些模块的详细信息。这些模块包含了大量的功能,例如处理文件、网络通信、字符串操作、数学运算等。使用这些模块无需额外安装,因为它们随着Python的安装而自动安装。
你可以使用
help('modules')
或help('modulename')
来查看所有内置模块或特定模块的文档。 -
第三方开源模块: 这是由Python社区或其他开发者开发的模块,不包含在Python标准库中。你可以使用工具如
pip
(Python的包管理工具)来安装这些模块。例如,你可以运行pip install 模块名
来安装你需要的第三方模块。这些模块包括各种用途,比如数据科学、Web开发、机器学习等领域的库。 -
自定义模块: 这是由你自己编写的模块,以供你的项目或其他程序使用。通过将相关功能组织成模块,你可以更好地组织代码并实现代码的重用性。
模块导入&调用
导入模块有以下几种方式:
import module_a #导入整个模块功能
module_a.xxx #调用
from module import xx # 导入某个模块下的某个方法 or 子模块
from module.xx.xx import xx as rename #导入后一个方法后重命令
from module.xx.xx import * #导入一个模块下的所有方法,不建议使用
注意:模块一旦被调用,即相当于执行了另外一个py文件里的代码
import module_a
导入整个模块功能
import os
os.mkdir("testdir")
from module import xx
导入某个模块下的某个方法 or 子模块
from os import system
system("df -h")
from module.xx.xx import xx as rename
导入后一个方法后重命令
from django.contrib.auth import authenticate as auth #从django.contrib.auth导出authenticate模块,并重命名为auth模块引入
auth() #调用auth模块,不能用authenticate了
from module.xx.xx import *
导入一个模块下的所有方法,**不建议使用
from os import *
os.system()
#运行结果
os.system()
^^
NameError: name 'os' is not defined
此时只能直接使用os下的所有模块,例如
from os import *
mkdir("testdir")
system("df -h")
这里会有严重的干扰问题,因为你不知道os下到底有多少命令,多少是冲突的,因此不建议使用from module.xx.xx import *
,应该以import module_a
模式导入整个模块功能,在用os.xxx()
调用
自定义模块
创建一个.py文件,就可以称之为模块,就可以在另外一个程序里导入
创建一个first_mod.py
文件,写入代码:
def nihao():
print("调用nihao函数时,我会被打印出来")
print("调用自定义模块first_mod时,我会被打印出来")
在同级目录下,创建模块.py
直接导入import first_mod
模块,点击运行。我们可以看到,模块first_mod.py
被运行了一遍,并且有回显
注意:模块一旦被调用,即相当于执行了另外一个py文件里的代码
模块的查找路径
当我把执行文件的路径挪到其他路径下的时候(自定义模块和执行文件不在一个目录下),就出现了ModuleNotFoundError
模块找不到的现象
#运行结果
Traceback (most recent call last):
File "D:\Python\05 模块和包\testdir\模块.py", line 1, in <module>
import first_mod
ModuleNotFoundError: No module named 'first_mod'
我们可以用内置标准模块sys
命令,查看python解释器的系统变量路径
import sys
print(sys.path) #显示路径.它是一种列表的形式显示的,为了方便排版展示,我进行了换行
['D:\\Python\\py基础\\05 模块和包\\testdir',
'D:\\Python\\py基础',
'C:\\PyCharm 2021.3.3\\plugins\\python\\helpers\\pycharm_display',
'C:\\Users\\admin\\AppData\\Local\\Programs\\Python\\Python311\\python311.zip',
'C:\\Users\\admin\\AppData\\Local\\Programs\\Python\\Python311\\DLLs',
'C:\\Users\\admin\\AppData\\Local\\Programs\\Python\\Python311\\Lib',
'C:\\Users\\admin\\AppData\\Local\\Programs\\Python\\Python311',
'C:\\Users\\admin\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages'
'C:\\PyCharm 2021.3.3\\plugins\\python\\helpers\\pycharm_matplotlib_backend']
python的环境变量路径是有顺序的,并且是个列表。按照列表的顺序依次查找的[0, 1, 2, 3, 4, 5],而这个0号位置就是当前路径信息。D:\\Python\\py基础\\05 模块和包\\testdir
一般情况下,列表的0和1项是当前目录和project的根目录。这里就是'D:\\Python\\py基础\\05 模块和包\\testdir'
和'D:\\Python\\py基础'
我们为了想顺利运行代码,可以手动写死到指定路径,以实现模块可调用。(因为是列表,因此用append添加在sys.path的列表末尾即可)
import sys
mod_path = "D:/Python/py基础/05 模块和包" #这是一个固定的写死路径。
sys.path.append(mod_path)
import first_mod
上面这是一个固定的写死路径,如果代码一旦给其他人使用就会出现路径问题,因此——我们可以用一个更动态的使用方法:使用__file__
拿到文件的路径
print(__file__)
#执行结果
D:\Python\py基础\05 模块和包\testdir\模块.py
此时我们拿到了文件的绝对路径.之后再做一个操作:用os.path.dirname()
当前文件的上层目录
import os
mod_path = os.path.dirname(__file__)
print(mod_path)
#执行结果
D:\Python\py基础\05 模块和包\testdir
目标目录是再上一层目录,为此,我们再套用一次os.path.dirname()
,以获得再上层的目录
import os
mod_path = os.path.dirname(os.path.dirname(__file__))
print(mod_path)
#执行结果
D:\Python\py基础\05 模块和包
为此,调用自定义模块的动态路径调用方法如下:
import sys
import os
mod_path = os.path.dirname(os.path.dirname(__file__))
print(mod_path)
sys.path.append(mod_path)
import first_mod
这是MAC系统电脑的路径显示(注意不同的电脑可能输出的不太一样)
注意:MAC系统列表第一个元素为空,即代表当前目录,所以你自己定义的模块在当前目录会被优先导入。
你导入一个模块时,Python解释器会按照上面列表顺序去依次到每个目录下去匹配你要导入的模块名,只要在一个目录下匹配到了该模块名,就立刻导入,不再继续往后找。
我们自己创建的模块若想在任何地方都能调⽤用,那就得确保你的模块文件至少在模块路径的查找列表中。我们一般把自己写的模块放在一个带有“site-packages”字样的目录里,我们从网上下载安装的各种第三方的模块一般都放在这个目录。这样就省去了引用路径的麻烦。
第3方开源模块安装
https://pypi.org/是python的开源模块库,截止2023年12月4日 ,已经收录了498,225个来自全世界python开发者贡献的Progects,几乎涵盖了你想用python做的任何事情。事实上每个python开发者,只要注册一个账号就可以往这个平台上传你自己的模块,这样全世界的开发者都可以容易的下载并使用你的模块。
如何下载第3方开源模块代码?
- 直接在上面这个页面上点download,下载后,解压并进入目录,执行以下命令完成安装
#编译源码 python3 setup.py build #安装源码 python3 setup.py install
- 直接通过pip3安装
pip3 install paramiko #paramiko 是模块名
pip命令会自动下载模块包并完成安装。软件一般会被自动安装你python安装目录的这个子目录里
/your_python_install_path/3.11/lib/python3.11/site-packages
pip命令默认会连接在国外的python官⽅方服务器下载,速度比较慢,你还可以使用国内的豆瓣源,数据会定期同步国外官网,快好多
pip3 install -i http://pypi.douban.com/simple/ PyTyrion --trusted-host pypi.douban.com #PyTyrion是模块名
-i 后面跟的是豆瓣源地址,
--trusted-host
得加上,是通过网站https安全验证用的。如果你使用的是 HTTPS 源,一般来说,你不需要添加--trusted-host
选项,因为 HTTPS 本身提供了安全的通信。pip3 install -i https://pypi.douban.com/simple/ PyTyrion
3、我们还可以通过PyCharm直接安装(文件——设置——Python解释器——点击加号)在线安装软件包(可能被墙)
我们可以在这里管理仓库(把全球的包改成国内)
阿里云pip源地址是:https://mirrors.aliyun.com/pypi/simple/
一般来说,使用阿里源进行pip安装并没有版本要求。阿里源是阿里云提供的一个公共源,它提供了许多常用的Python包和库的最新版本,因此在使用阿里源进行pip安装时,通常会安装到最新版本的包或库。
清华大学的pip源地址是:https://pypi.tuna.tsinghua.edu.cn/simple/
请注意,在使用这个源时,确保你的pip版本是10.0.0或更高版本,并使用pip install [包名] -i [pip源URL]
的命令进行安装。
例如,要安装pytest包,可以运行pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple/
。
豆瓣源的pip地址是:https://pypi.douban.com/simple/
请注意,在使用豆瓣源时,确保你的pip版本是10.0.0或更高版本。输入以下命令,将豆瓣源添加到pip源列表中:pip install -i https://pypi.douban.com/simple/ pip
下载后,直接导入使用就可以,跟自带的模块调用方法无差
包(Package)的概念
在Python中,包(Package)是一种用于组织模块(Module)的方式。包是一个包含特殊的 __init__.py
文件的目录,这个文件可以为空,也可以包含包级别的初始化代码或文档。
包的主要目的是为了将相关的模块组织在一起,以便更好地管理和维护项目的结构。通过使用包,你可以创建一个层次化的模块结构,使得代码更具可读性和可维护性。
如何创建一个包
只需要在目录下创建一个空的__init__.py
文件, 这个目录就变成了包。这个文件叫包的初始化文件,一般为空,当然也可以写东西。当你调用这个包下及其任意子包的任意模块时,这个__init__.py
文件都会先执行。
示例:假设你有一个名为 Game_Package
的包,它的目录结构如下:
如图中,我们可以看到,这个叫Game的包中包含了1个文件目录:__init__.py
,和三个扩展子包Sound
、Image
、Level
目录结构如下
Game/
|-- __init__.py
|-- Sound/
| |-- __init__.py
| |-- load.py
| |-- play.py
| |-- pause.py
|-- Image/
| |-- __init__.py
| |-- open.py
| |-- change.py
| |-- close.py
|-- Level/
| |-- __init__.py
| |-- start.py
| |-- load.py
| |-- over.py
包的导入
__init__.py
文件的作用:
当你导入一个包或子包时,该包及其所有父级包的 __init__.py
文件都会被依次执行一次。这是 Python 中包初始化的机制。这个机制确保了在导入包或子包时,包内的一些初始化代码可以得到执行,以便为后续的模块和功能做好准备。因此,当你想初始化加载一些动作,就可以都写入到__init__.py
中
- 如果你导入的是一个包,则首先执行该包的
__init__.py
文件。 - 如果导入的是子包,则按照从上到下的层次结构逐级执行父级包的
__init__.py
文件,然后执行子包的__init__.py
文件。
在其他地方,你可以使用以下方式导入这个包中的模块
# 导入整个包
import Game
# 导入子包及其模块
from Game.Sound import load, play, pause
from Game.Image import open, change, close
from Game.Level import start, load, over
注意:
- 你可以使用
import Game
导入整个包。(此时,Game 包的 __init__.py 文件以及 Game 包下的 Sound、Image、Level 这三个子包的各自的 __init__.py 文件都会被依次执行。这确保了整个包及其子包在导入时都能够执行必要的初始化代码。例如,你可以在这些 __init__.py 文件中进行一些包级别的设置或引入子模块,以确保包的功能正常运行。) -
对于子包,你可以使用
from Game.Sound import load
的形式导入模块。(此时,Game 包的 __init__.py 会被执行,因为你导入了整个包。Game.Sound 子包的 __init__.py 也会被执行,因为你导入了子包。) - 如果你发现模块名冲突,你可以使用别名来解决,例如
from Game.Level import load as level_load
。
**注意** 如果 Sound
包下没有 __init__.py
文件,你仍然可以这样引用其子模块from Game.Sound import load, play, pause
,但是 Sound
包本身将不会被识别为包。在这种情况下,Sound
就是一个普通的目录,而不是一个包。但如果你尝试导入整个Sound Game.Sound
本身而没有 __init__.py
文件,可能会引发 ImportError。
前文有说到:一般情况下,目录列表的0和1项是当前目录和project的根目录,(这里project根目录是py基础)我们可以利用根目录这种机制配合导入包引用first_mod文件,依旧可以运行
在Windows中,Python的内置模块一般是放在Lib文件夹下,例如:C:\Program Files\Python\Python311\Lib
或C:\Users\admin(你的用户账号)\AppData\Local\Programs\Python\Python311\Lib
需要注意的是,如果你使用虚拟环境(virtual environment),那么你的内置模块将位于虚拟环境目录下的 Lib
子目录中,而不是全局 Python 安装目录。
我们可以用命令来获取到内置模块的数量和内置包的数量
import sys
print(len(sys.modules)) # 获取内置模块的数量
print(len(sys.builtin_module_names)) # 获取内置包的数量
#运行结果
64
67
第三方的 Python 模块和包通常被安装在系统的 site-packages
目录中。这个目录是 Python 安装时创建的,用于存放所有通过包管理工具(例如 pip
)安装的第三方库。
在 Windows 上,site-packages
目录通常位于 Python 安装目录下的 Lib
目录中。路径的形式可能如下:
例如:C:\Program Files\Python\Python311\Lib\site-packages
或 C:\Users\admin(你的用户账号)\AppData\Local\Programs\Python\Python311\Lib\site-packages
同理:如果你使用虚拟环境(virtual environment),那么你的内置模块将位于虚拟环境目录下的 Lib
子目录中\Lib\site-packages
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)