什么是模块(Module)?

在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。

为了编写可维护的代码,我们把很多代码按功能分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就可以称之为一个模块(Module)。

使用模块有什么好处?

  1. 最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
  2. 使用模块还可以避免函数名和变量名冲突。每个模块有独立的命名空间,因此相同名字的函数和变量完全可以分别存在不同的模块中,所以,我们自己在编写模块时,不必考虑名字会与其他模块冲突

模块的三种分类,具体如下:

  1. 内置标准模块(标准库): 这是Python语言自带的模块,你可以在Python的官方文档中找到这些模块的详细信息。这些模块包含了大量的功能,例如处理文件、网络通信、字符串操作、数学运算等。使用这些模块无需额外安装,因为它们随着Python的安装而自动安装。

    你可以使用 help('modules')help('modulename') 来查看所有内置模块或特定模块的文档。

  2. 第三方开源模块: 这是由Python社区或其他开发者开发的模块,不包含在Python标准库中。你可以使用工具如pip(Python的包管理工具)来安装这些模块。例如,你可以运行 pip install 模块名 来安装你需要的第三方模块。这些模块包括各种用途,比如数据科学、Web开发、机器学习等领域的库。

  3. 自定义模块: 这是由你自己编写的模块,以供你的项目或其他程序使用。通过将相关功能组织成模块,你可以更好地组织代码并实现代码的重用性。

模块导入&调用

导入模块有以下几种方式:

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方开源模块代码?

  1. 直接在上面这个页面上点download,下载后,解压并进入目录,执行以下命令完成安装

    #编译源码
    python3 setup.py build #安装源码
    python3 setup.py install
  2. 直接通过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 ,和三个扩展子包SoundImageLevel目录结构如下

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

  1. 如果你导入的是一个包,则首先执行该包的 __init__.py 文件。
  2. 如果导入的是子包,则按照从上到下的层次结构逐级执行父级包的 __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\LibC:\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

Python——第五章:模块(Module)、自定义模块、第3方开源模块、包(Package)的更多相关文章

  1. Python第五章__模块介绍,常用内置模块

    Python第五章__模块介绍,常用内置模块 欢迎加入Linux_Python学习群  群号:478616847 目录: 模块与导入介绍 包的介绍 time &datetime模块 rando ...

  2. 简学Python第五章__模块介绍,常用内置模块

    Python第五章__模块介绍,常用内置模块 欢迎加入Linux_Python学习群  群号:478616847 目录: 模块与导入介绍 包的介绍 time &datetime模块 rando ...

  3. Knockout应用开发指南 第五章:创建自定义绑定

    原文:Knockout应用开发指南 第五章:创建自定义绑定 创建自定义绑定 你可以创建自己的自定义绑定 – 没有必要非要使用内嵌的绑定(像click,value等).你可以你封装复杂的逻辑或行为,自定 ...

  4. Python第五章实验报告

    一.实验项目名称:<零基础学Python>第五章实战.实例以及两道作业题 二.实验目的和要求:了解和掌握操作字符串的方法和正则表达式的应用 三.实验环境:IDLE(Python 3.9 6 ...

  5. 第五章 Odoo 12开发之导入、导出以及模块数据

    大多数Odoo 模块的定义,如用户界面和安全规则,实际是存储在对应数据表中的数据记录.模块中的 XML 和 CSV 文件不是 Odoo 应用运行时使用,而是载入数据表的手段.正是因为这个原因,Odoo ...

  6. 【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis

    [.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我们介绍了2种网关配置信息更新的方法和扩展Mysql存储,本篇我们将介绍如何使用Redis来实现网关的所有缓存功能,用到的文档及源码 ...

  7. nodejs 导入导出模块module.exports向外暴露多个模块 require导入模块

    .moudel.exports 导出模块 导出单个模块 // user.js moudel.exports = 函数名或者变量名: //app.js 导入 require('user.js') 当然. ...

  8. 流畅的python第五章一等函数学习记录

    在python中,函数是一等对象,一等对象是满足以下条件的程序实体 1在运行时创建 2能复制给变量或数据结构的元素 3能作为参数传给函数 4能作为函数的返回结果 高阶函数(接受函数作为参数或者把函数作 ...

  9. Docker | 第五章:构建自定义镜像

    前言 上一章节,主要是介绍了下Dockerfile的一些常用命令的说明.我们知道,利用Dockerfile可以构建一个新的镜像,比如运行Java环境,就需要一个JDK环境的镜像,但直接使用公共的镜像时 ...

  10. Python第五章-内置数据结构05-集合

    Python内置数据结构 五.集合(set) python 还提供了另外一种数据类型:set. set用于包含一组无序的不重复对象.所以set中的元素有点像dict的key.这是set与 list的最 ...

随机推荐

  1. Redis系列24:Redis使用规范

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  2. 其它——各主流Linux系统解决pip安装mysqlclient报错

    文章目录 一 CentOS(红帽) 二 Ubuntu 三 Windows 一 CentOS(红帽) #CentOS有Python.Mysql的开发工具包,安装后使用pip安装mysqlclient即可 ...

  3. Backgrounds

    有人私信要背景图,所以一起放出来了qwq 感觉这个博皮的动效选深色并且带点漂浮感的背景会比较好看(? 选图基本按这个标准选的,实际上比较亮的几张图已经被我手动拉低亮度了.(不过还是不太行/kk 备注里 ...

  4. Acwing76场周赛

    题目链接 这次还是只做出来两道题,前两题都挺简单的,注意第二题需要开long long不开会wa,代码粘上来,以后可能会看吧 第一题 #include<iostream> #include ...

  5. js 实现文件下载/文件导出。

    1. POST方式进行文件导出: // url 下载URL // fileName 下载文件名称 function exportFile(url, fileName) { let xhr = new ...

  6. synchronized 解决方案

    4.2 synchronized 解决方案 为了避免临界区的竞态条件发生,有多种手段可以达到目的. 阻塞式的解决方案:synchronized,Lock 非阻塞式的解决方案:原子变量 本次课使用阻塞式 ...

  7. HTTP 和 RPC 的区别

    一句话概括 RPC代表:Feign.Dubbo RPC 主要用于公司内部的服务调用,性能消耗低,传输效率高,服务治理方便. HTTP 代表:RestTemplate.HttpClient HTTP 主 ...

  8. 【pwn】整数溢出

    这是ctfshow上面的一道题 这边v1和v2定义时都是int,有符号整数,想让v1-v2=9,可以考虑负数,但是这个函数过滤了负号   if ( strchr(s, 45) )    return ...

  9. git如何使用?初始化仓库 提交代码

    首先 国内一般使用码云 注册码云 在ui界面创建仓库 一般只有一个readme 方法一: 第一步  git clone https://gitee.com/用户个性地址/HelloGitee.git ...

  10. java中ArrayList和LinkedList的区别

    Java中ArrayList和LinkedList都是List集合的实现类,它们都可以用来存储一组有序的元素,但是它们的内部实现方式不同,在使用时也有不同的适用场景. ArrayList是一个基于动态 ...