Python 模块--详细整理

3,593 阅读15分钟

Python 模块

在开发过程中,我们写的代码越来越多,如果把它们都写在一个文件中,就会变得越来越长,也越来越难以维护。

后来我们学习了函数,它可以将一段重复使用的代码封装到一个函数中,这样我们就可以轻松地重复使用它了,同时代码也更易于维护。

接着,我们学习了,类可以组织代码并将其封装,这样我们可以更好地管理代码。

其实模块就是函数功能的扩展。因为模块其实就是实现一项或多项功能的程序块。

Python 模块是指一个包含 Python 定义和语句的文件,它可以被其他程序导入和使用,它们可以减少代码的重复编写,提高代码的可读性和可复用性,还能够有效地组织和管理代码。

Python 是一种高级编程语言,可以使用许多内置模块和第三方模块来扩展其功能。 模块是 Python 代码的重要组成部分,一种重要的编程技巧是将代码组织成可重用的模块。

通过使用模块,我们可以实现代码重用,简化代码和代码分发,扩展功能以及简化任务等方面的意义。

  1. 代码重用:模块允许开发人员将代码定义为独立的、可重用的组件。这使得可以多次使用同一段代码,而无需重复编写代码。

  2. 简化代码:模块可以使代码更容易编写,更易于理解和维护。通过将代码分解为模块,程序员可以避免在单个文件中编写大型代码块的问题。

  3. 简化代码分发:模块可以使代码分发更加简单和可控。开发人员可以将其代码分解为小模块,然后将这些模块分开打包,以便在需要的时候可以轻松地分发它们。

  4. 扩展功能:Python 模块可用于扩展 Python 语言的功能。这允许 Python 开发人员在语言中添加自定义功能,以满足其独特的需求。

  5. 简化任务:使用模块可以使许多任务变得更加简单。例如,使用 Python 编写 GUI 程序通常需要使用大量外部库和模块,而这些库和模块可以使 GUI 程序的创建过程更加容易。

1 模块创建

除了使用别人编写好的模块,我们还可以自己编写模块。

创建一个模块非常简单,只需要将代码写入一个 .py 文件即可。

在模块文件中定义的函数、变量等可以在其他程序中导入和使用。 例如,我们可以创建一个名为 mymodule.py 的模块文件,其中包含如下代码:

def greeting(name):
    print("Hello, " + name)

person = {
    "name": "Alice",
    "age": 25,
    "country": "USA"
}

然后在另一个 Python 文件中导入并使用这个模块:

import mymodule

mymodule.greeting("Bob")

print(mymodule.person["name"])

以上代码导入了 mymodule 模块,并使用其中的函数 greeting() 和字典 person

2 模块导入

要使用 Python 的模块,我们需要先导入它。Python 中有三种导入模块的方法:

  • import 语句 可以导入模块中的特定函数或变量

  • from ... import 语句 可以导入模块中的特定函数或变量

  • __import__() 函数 可以动态地导入模块

  • 将整个模块(somemodule)导入:import somemodule

  • 从某个模块中导入某个函数: from somemodule import somefunction

  • 从某个模块中导入多个函数: from somemodule import firstfunc, secondfunc, thirdfunc

  • 将某个模块中的全部函数导入: from somemodule import *

例如,我们以标准库中的 math 模块为例,分别看看这三种方法的用法:

import math

print(math.pi)

from math import pi

print(pi)

math = __import__('math')

print(math.pi)

以上代码分别使用了不同的方法导入模块,并输出了 math 模块中的常量 pi 的值。

3 模块属性

Python 中的模块属性是指在一个模块中定义的变量、函数或类等可调用对象。

模块是 Python 程序的基本组成单位之一,一个模块就是一个包含 Python 代码的文件,它可以包含 Python 所需的任何内容,例如变量、函数、类、以及可导入的子模块等。

模块属性的定义是在模块文件中通过语法,如下面的例子所示:

# module1.py

x = 10    # 定义一个模块变量x

def func():    # 定义一个函数func
    print("Hello, world!")

class MyClass:    # 定义一个类MyClass
    def __init__(self, name):
        self.name = name

    def say_hello(self):
        print("Hello, {}!".format(self.name))

在上面的例子中,x、func 和 MyClass 都是模块属性。

要在另一个模块中使用这些属性,可以使用 import 语句将模块导入。导入模块使得我们可以使用其中定义的所有对象。例如,在另一个名为 test.py 的模块中,可以这样使用 module1.py 中定义的属性:

# test.py
import module1

# 使用模块中定义的变量
print(module1.x)

# 调用模块中定义的函数
module1.func()

# 创建模块中定义的类的实例
obj = module1.MyClass("John")
obj.say_hello()

注意,在 Python 中,变量、函数和类的命名空间都是在模块级别,这意味着模块中定义的属性可以直接使用,而不需要使用类似于 Java 中的类名限定符。

另一方面,如果一个模块中定义了很多属性,我们可以只导入我们确实需要的属性。以下是一些导入模块的常见方式:

# 只导入模块中的某些属性
from module1 import func, MyClass

# 导入模块中的所有属性
from module1 import *

需要注意的是,使用 from ... import 语句导入属性时,我们需要确保属性的名称不会与当前模块中的其他属性发生冲突。

3.1 name

__name__是 Python 内置的一个特殊变量,它表示当前模块的名字。

当 Python 解释器载入一个模块时,将会为这个模块创建一个名为__name__的变量,并将其指向该模块的名字。

当我们从该模块导入其它模块时,该模块的__name__属性将被置为导入它的模块的名字。

当模块作为脚本运行时,该模块的__name__将被自动设置为"__main__"。

这是因为当 Python 解释器把脚本作为运行的主程序时,将为该脚本创建一个名为__main__的变量,并把它当做该程序的名字。

在这种情况下,我们可以通过判断__name__是否为"__main__"来执行一些测试代码或者只在该模块作为脚本被运行时执行特定代码,而在该模块作为模块被导入时不执行。

例如,我们可以定义一个 test 函数,在该模块作为脚本被运行时执行该函数。具体的示例代码如下:

def test():
    print("This is a demo function")

if __name__ == "__main__":
    test()

上述代码中,当该模块被导入时,由于__name__不等于"__main__",不会执行test函数,但是当我们直接运行该模块时,由于__name__等于"__main__",将会自动调用test函数打印输出"This is a demo function"。

__name__属性的使用可以让我们编写更加灵活和通用的模块,同时还可以提升程序的可重用性和可维护性。

4 模块搜索路径

当我们导入模块时,Python 会在一些预定义的目录下搜索模块文件。

Python 的搜索路径可以通过 sys.path 变量查看。例如,在 Python 命令行中输入:

import sys
print(sys.path)

会输出一个列表,其中包含了 Python 解释器搜索模块文件的路径。我们可以在这些路径下创建模块文件,以便 Python 能够找到并导入它们。

我们还可以使用 PYTHONPATH 环境变量来修改 Python 的搜索路径。例如,在 Unix 系统中,可以在 .bashrc 文件中添加以下语句以添加自定义路径:

export PYTHONPATH="/path/to/my/modules"

5 模块相关关键字和内置函数

当涉及到 Python 模块的导入时,有几个内置的、与模块有关的关键字和函数。下面是对其中一些最常用的进行简要说明:

  1. import:这是最常用的关键字之一,它用于将整个模块导入当前的作用域中。例如:
import math

这句话将会把 Python 的math库导入到当前的程序中。这将让我们可以直接使用math库中定义的所有函数和常量。

  1. from:这个关键字用于从模块中导入指定的属性。这样做可以避免载入整个模块,从而节省资源。例如:
from math import pi

这句话将从 math 库中导入 pi 常量。可以将多个属性从同一个模块导入,也可以从不同的模块中导入多个属性。

  1. as:有时候,我们可能需要给导入的模块或属性起一个不同的名字,以方便程序的使用。这时,我们可以使用as关键字来指定一个别名。例如:
import math as m

这应该是所有替代方案中使用最广泛的一个,它将math库导入到当前的作用域中,并将其别名定义为“m”。在后面的代码中,我们可以使用“m”来代替“math”。在使用较长的库名称时,as关键字特别有用。

  1. dir()dir()是一个内置函数,用于返回变量、模块、对象的属性。例如:
import math
print(dir(math))

这个代码运行后将会返回math模块中定义的所有属性的列表。这样可以帮助我们快速查看模块的内容,以便更容易地编写代码。

  1. reload():如果我们对导入的模块做了一些修改,那么可以使用reload()函数重新加载模块。例如:
import my_module
# 编辑my_module
reload(my_module)

这个代码将会重新载入my_module模块,以便能够应用其中的修改。需要注意的是,在 Python 3 中,这个函数被移动到了importlib模块。

6 模块重载

在模块使用过程中,可能需要修改模块文件的内容。但是,Python 只会在第一次导入模块时将其编译为字节码,在后续导入时不会再次编译,这就会导致修改后的代码没有得到执行。为了解决这个问题,我们可以使用 reload() 函数。例如:

import mymodule
reload(mymodule)

以上代码重新导入并执行 mymodule 模块。需要注意的是,reload() 函数只能重新加载之前已经被加载的模块,如果第一次导入模块失败,reload() 也无法修复它。

7 命名空间和作用域

当我们导入模块、定义函数和变量时,它们都有自己的命名空间和作用域。

Python 中的命名空间是指在其中定义的变量名和函数名的集合,命名空间可以通过字典来实现。

作用域是指一个变量或函数的可访问范围,通常与命名空间相关联。

Python 中有三种作用域:局部、全局和内建。

  • 局部作用域指定义在函数内部的变量。
  • 全局作用域指定义在模块内部的变量,在模块中的任何地方都可以访问。
  • 内建作用域指 Python 内建函数和变量,如 print()len()

当 Python 执行一个函数时,它会先在局部作用域中查找变量,如果找不到,则会在全局作用域中查找。如果还找不到,则会在内建作用域中查找。如果仍然找不到,则会抛出 NameError 异常。

8 命名冲突

在程序中,可能会存在多个相同名称的函数或变量,这就会导致命名冲突。为了避免这种情况,我们可以使用模块命名空间,例如 mymodule.greeting(),这样模块的命名空间就不会与其他命名空间冲突。

9 包

包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

比如一个模块的名称是 A.B, 那么他表示一个包 A 中的子模块 B

Python 的“包”是由多个模块组成的一个目录树结构,它用于组织 Python 中的代码和数据。包的目录必须包含一个名为__init__.py的文件,该文件可以为空,也可以包含初始化包的代码。如果没有__init__.py文件,Python 将不会将该目录识别为包。包可以帮助我们更好地组织 Python 代码和数据,并且可以使得程序更易于维护和管理。

将多个模块组合成一个包有几个优点:

  1. 命名空间管理:包使得代码和数据的命名空间得以分开管理,从而避免了名称冲突。
  2. 模块重用:包可以使得模块被重用,即它们可以在不同的程序中被使用。
  3. 代码组织:包可以帮助程序员更好地组织 Python 代码和数据,从而使代码更易于维护和管理。

在 Python 中,可以使用import语句从包中导入模块。例如,如果我们有一个名为mypackage的包,它包含一个名为mymodule的模块,我们可以使用以下语句将其导入:

import mypackage.mymodule

或者,我们也可以从 mypackage 中导入 mymodule:

from mypackage import mymodule

从包中导入模块时,Python 会自动搜索sys.path中的所有目录来查找模块。如果包含__init__.py的文件夹被找到,Python 就会将它识别为一个包,并搜索该目录的__init__.py文件和其他模块。如果 name 参数指定的模块名被找到,则返回该模块;否则,抛出ImportError异常。

10 常用模块包

当谈到 Python 的模块时,有许多常用的内置模块。这些模块包括:

  1. math:用于执行数学运算的一组函数。包括三角函数、指数函数、对数函数和常数 Pi 等。
  2. datetime: 用于进行日期和时间操作的模块。可以用于比较、计算、格式化日期和时间,以及执行其他相关操作。
  3. os:用于访问操作系统的一些功能的模块。可以用来执行操作系统的文件和目录操作、环境变量、进程控制等。
  4. random:用于生成随机数和随机选择的模块。可以生成伪随机数序列和打乱序列中项的顺序等。
  5. requests: 用于调用 HTTP/1.1 API 的 Python 库。它允许发送 HTTP 请求,随后接收响应并解析数据。
  6. re:用于正则表达式操作的模块。可以使用正则表达式来匹配字符串、替换字符串或切割字符串。
  7. json:用于处理 JSON 格式的数据的模块。可以将 Python 数据结构转换为 JSON 格式,并将 JSON 格式数据转换为 Python 数据结构。

此外还有许多其他的模块可供使用。这个列表只是其中一部分。了解这些模块以及它们的功能对于 Python 编程非常有帮助。

11 PIP

11.1 PIP简介

Python PIP,全称为Python Installation Package,是Python语言的官方包管理器。Python PIP可以自动搜索、下载、安装、升级和卸载Python包。它的优点是自动处理包的依赖关系,即它会自动检查包是否需要其他依赖项,如果需要,则自动下载和安装这些依赖项。

Python PIP是一个命令行工具,可以通过命令行终端使用。在使用之前,需要先安装Python软件,具体安装及配置方法可以参考Python官方文档。

11.2 PIP的安装

在安装Python模块之前,需要先安装Python PIP包管理器。

Python 2.7.x和Python 3.4及以上版本通常自带pip,如果你的电脑上有多个Python版本,需要确认使用哪个Python版本安装pip。可以使用以下命令检查是否安装pip:

$ pip --version

如果输出pip的版本信息,则说明pip已经安装。

如果你的Python版本自带的pip无法使用或者需要同时安装多个版本的pip,可以使用以下方式安装:

  • 在Windows上,下载get-pip.py文件并执行
$ python get-pip.py
  • 在Linux/macOS上,执行以下命令:
$ sudo apt-get install python-pip

$ sudo yum install python-pip

$ sudo easy_install pip

11.3 PIP的常用命令

使用pip,我们可以执行以下一些常用命令:

  1. 版本和帮助
$ pip --version               # 查看版本信息
$ pip help                    # 查看帮助信息
  1. 搜索包
$ pip search pakage_name      # 搜索包,查看包信息
  1. 安装包
$ pip install package_name    # 安装包
  1. 升级包
$ pip install --upgrade package_name   # 升级包
  1. 卸载包
$ pip uninstall package_name  # 卸载包
  1. 查看已安装的包信息
$ pip list                    # 查看已安装的包信息
  1. 导出/导入已安装包的信息
$ pip freeze > requirements.txt    # 导出已安装的包及其版本信息到requirements.txt
$ pip install -r requirements.txt  # 从requirements.txt导入已安装的包及其版本信息

11.4 PIP的常见问题及解决方案

在使用pip时,可能会出现一些常见问题,本章节将介绍这些问题及其解决方案。

11.4.1 更新pip

在某些情况下,原来安装的pip版本会有问题,需要更新。有多种方式可以更新pip。

  • pip自身更新命令

    $ pip install -U pip
    

    这将会更新pip并安装最新版本。

  • 使用easy_install安装

    $ easy_install -U pip
    
  • 手动安装

    $ wget https://bootstrap.pypa.io/get-pip.py
    $ python get-pip.py
    

11.4.2 找不到包

有时候在使用pip安装时会出现找不到包的问题,可能是因为没有添加正确的源地址。可以使用以下命令添加源:

$pip install package_name -i https://pypi.tuna.tsinghua.edu.cn/simple

其中,pypi.tuna.tsinghua.edu.cn/simple 是清华镜像站的源地址,也可以替换成其他可用的源。

11.4.3 权限不足

在使用pip时,可能因为权限不足而导致失败,可以使用以下方法解决:

  • Linux/MacOS系统下,使用sudo

    $ sudo pip install package_name
    
  • pip升级到21.0或以上版本,使用--user选项安装。

    $ pip install --user package_name