模块

模块是用来组织程序结构和创建可重用库的一种方式。一个模块通常存储在一个单独的 .py 文件中。许多模块是标准库的一部分,你也可以创建自己的模块。Python 会在当前目录和其他位置搜索模块;通过扩展 PYTHONPATH 环境变量以及其他方式,可以增加模块搜索的位置。

导入模块

要使用模块提供的函数,你需要导入模块:

import math
print(math.sqrt(10))

上面的代码导入了 math 标准模块,并且使该模块中的所有函数都可以通过模块名称来访问。

你可以为模块指定一个别名:

import math as Mathematics
print(Mathematics.sqrt(10))

你也可以只导入一个函数,使其不需要模块名前缀就能直接使用:

from math import sqrt
print(sqrt(10))

你还可以为导入的函数指定一个别名:

from math import cos as cosine
print(cosine(10))

你可以一次性导入多个模块:

import os, sys, re

也可以在函数内部延迟导入模块:

def sqrtTen():
  import math
  print(math.sqrt(10))

这种导入只会在函数被调用时发生。

你可以使用星号 * 导入模块中的所有函数,而不需要模块名前缀:

from math import *
print(sqrt(10))

然而,如果你在函数内部使用这种方式,在 Python 2 中会收到警告,在 Python 3 中会出错:

def sqrtTen():
  from math import *
  print(sqrt(10))

你可以通过 try...except 语句捕捉模块未找到的情况:

try:
  import custommodule
except ImportError:
  pass

模块的不同

模块可以是以下几种型:

  • Python 文件
  • 共享对象(在 Unix 和 Linux 中)以 .so 为后缀
  • DLL(在 Windows 中)以 .pyd 为后缀
  • 目录

模块加载的顺序由 sys.path 控制。当前目录始终包含在搜索路径中。

目录应包含一个名为 __init__.py文件,该文件应包含在加载该目录时执行的 Python 命令。

创建与 Python 交互的 DLL 则另有专门的部分进行讲解。

检查模块是否导入

你可以检查一个模块是否已导入,方法如下:

if "re" in sys.modules:
  print("Regular expression module is ready for use.")

创建模块

文件创建模块

创建模块的最简单方法是拥有一个名为 mymod.py文件,该文件要么位于由 PYTHONPATH 变量识别的目录中,要么(更简单)就在当前工作目录中。如果你有以下文件 mymod.py

class Object1:
        def __init__(self):
                self.name = 'object 1'

你可以导入这个模块并创建 Object1 的实例:

import mymod
myobject = mymod.Object1()
from mymod import *
myobject = Object1()

从目录创建模块

对于较大的项目,将所有存储在一个文件中并不可行。通常,将所有文件存储在目录中并通过一个命令加载所有文件更为简便。每个目录需要有一个 __init__.py 文件,该文件包含在加载该目录时执行的 Python 命令。

假设我们有另外两个对象 Object2Object3,我们希望通过一个命令加载所有三个对象。然后我们创建一个名为 mymod 的目录,并在其中存储三个文件Object1.pyObject2.pyObject3.py。这些文件可以包含每个文件的一个对象,但这不是必须的(尽管这样做更清晰)。然后我们会写一个 __init__.py 文件

from Object1 import *
from Object2 import *
from Object3 import *

__all__ = ["Object1", "Object2", "Object3"]

前面三条命令告诉 Python 在有人加载模块时该做什么。最后的 __all__ 定义告诉 Python 当执行 from mymod import * 时该做什么。通常,我们希望在模块的不同部分之间使用一些模块中的部分,例如我们希望在 Object2 中使用 Object1。我们可以通过 from . import * 命令轻松做到这一点,如下所示:

from . import *

class Object2:
        def __init__(self):
                self.name = 'object 2'
                self.otherObject = Object1()

现在我们可以像上一节中那样导入 mymod 模块。

使程序可用作模块

为了使程序既能作为独立的命令行程序运行,又能作为模块使用,建议将所有代码放入函数和方法中,指定一个主函数,并在 __name__ 内置变量等于 '__main__' 时调用该主函数。这样做的目的是确保当程序作为模块导入时,主函数中的代码不会被调用;如果代码直接放在函数外面,导入时代码会被调用。

你的程序(存储在 mymodule.py 中)可以如下所示:

def reusable_function(x, y):
  return x + y

def main():
  pass
  # 任何你喜欢的代码

if __name__ == '__main__':
  main()

使用上述程序的方式如下:

from mymodule import reusable_function
my_result = reusable_function(4, 5)

扩展模块路径

当请求导入时,模块会在由 sys.path 访问的目录(和 zip 文件?)中进行搜索。可以通过以下方式扩展模块路径:

import sys
sys.path.append("/My/Path/To/Module/Directory")
from ModuleFileName import my_function

在上面,如果 ModuleFileName.py 位于 /My/Path/To/Module/Directory,并且包含 my_function 的定义,那么第二行确保第三行正常工作。

模块名称

模块名称似乎仅限于字母数字字符和下划线,不能使用破折号。虽然可以创建并运行 my-module.py,但导入时 my-module 会失败。模块的名称是模块文件的名称去掉 .py 后缀。

模块名称区分大小写。如果模块文件叫做 MyModule.py,那么 import mymodule 会失败,而 import MyModule 是有效的。

PEP 0008 推荐模块名使用全小写字母,可能会使用下划线。

内置模块

内置模块不同于标准库的一部分。例如,re 不是内置模块,而是一个用 Python 编写的模块;与此相对,_sre 是一个内置模块。

获取内置模块名称列表:

print(sys.builtin_module_names)
print("_sre" in sys.builtin_module_names) # True
print("math" in sys.builtin_module_names) # True
最后修改: 2025年01月31日 星期五 00:33