在 Python 中导入模块
要使用任意模块中的功能,您需要先在当前程序中导入它。您需要使用 import 关键字并跟上目标模块名。当解释器遇到 import 语句时,就会将该模块导入到当前程序中。
您可以通过在模块名后使用点号(.)运算符来调用模块中的函数。
先来看如何使用标准库模块。下面的示例中,将 math 模块导入程序,以便使用 sqrt() 函数。
import math # Import the math module
num = 4
print(math.sqrt(num)) # Call the sqrt() function from the math module
出于效率考虑,每个模块在一次解释器会话中只会被导入一次。因此,如果您修改了模块,必须重启解释器。
如果您想重新加载已导入的模块(例如编辑之后),请使用 importlib.reload()。
请注意,旧的内置函数 reload() 在 Python 3 中已不存在——在 Python 3.4+ 中,importlib.reload() 是当前且官方推荐的模块重载方式。
import importlib
importlib.reload(module_name)
注意:不建议重载 sys、__main__、builtins 等关键模块。许多扩展模块并未设计为可多次初始化,重载时可能以不可预期的方式失败。开发阶段请仅重载您自己的模块。
即将推出:Python 正在引入“延迟导入”(lazy imports)。它会将模块的加载推迟到首次使用时,从而加快启动速度。这很有用,尤其在大型项目中,通常会在文件顶部导入许多模块,但并不立即需要它们。
如何编写您自己的 Python 模块
现在您已经学会了如何在程序中导入模块,是时候编写自己的模块并在另一个程序中使用它了。编写模块与编写其他 Python 文件并无二致。让我们先在文件 calculation.py 中编写一个用于加减两个数的函数。
def add(x,y):
return (x+y)
def sub(x,y):
return (x-y)
如果您尝试在命令行直接执行该脚本,不会有任何输出,因为您并未指示程序执行某个操作。请在同一目录下创建另一个名为 module_test.py 的 Python 脚本,并写入以下代码。
import calculation #Importing calculation module
print(calculation.add(1,2)) #Calling function defined in the calculation module
如果您执行 module_test.py,将会看到输出为 "3"。当解释器遇到 import 语句时,它将 calculation 模块导入到您的代码中,随后通过点号运算符,您得以访问 add() 函数。
使用 if __name__ == "main" 保护可运行代码
在编写模块时有一个重要习惯:将只希望在直接运行(而非被导入时)执行的代码,放入 if __name__ == "__main__" 保护块中。
# calculation.py
def add(x, y):
return x + y
def sub(x, y):
return x - y
if __name__ == "__main__":
# This only runs when you execute calculation.py directly
# It will NOT run when another script imports this module
print(add(1, 2))
__name__ 设为 "__main__"。当它被另一个脚本导入时,__name__ 会被设为模块的文件名。因此,上面的 print 语句在他人将 calculation 导入到其程序时不会意外执行。在 Python 中导入模块的其他方式
还有更多导入模块的方法:
-
from .. import语句 -
from .. import *语句 -
为导入的模块重命名
使用 from module import name
from..import 语句允许您仅从模块中导入特定的函数/变量,而不是导入全部。在前面的示例中,当您将 calculation 导入到 module_test.py 时,add() 和 sub() 两个函数都会被导入。但如果您只需要 add() 函数呢?下面的示例演示了 from..import 的用法。
from calculation import add
print(add(1,2))
在上面的示例中,只导入并使用了 add() 函数。注意这里直接使用了 add()?您现在无需再写模块名即可直接访问它。您也可以在导入语句中用逗号分隔导入多个属性。请看下面的示例:
from calculation import add,sub
使用 from module import *
使用该语句可以导入模块的所有属性。这样,被导入模块的所有名称都会在您的代码中可见。
下面的示例演示了 from .. import * 的用法:
from calculation import *
print(add(1,2))
print(sub(3,2))
注意,在专业开发中应尽量避免使用 from..import 和 from..import*。它会用该模块中的所有名称污染您的命名空间,使得阅读代码时难以判断函数来自何处,并且可能悄然覆盖您已定义的名称。请改用显式导入。
在 Python 中为模块重命名
您可以为要导入的模块重命名:当您希望给模块一个更有意义的名称,或模块名过长不便重复书写时,这很有用。您可以使用 as 关键字为其起别名。以下示例展示了如何在程序中使用它。
import calculation as cal
print(cal.add(1,2))
将 calculation 重命名为 cal 能为您省下一些输入工作。
注意,此时您将不能再使用 calculation.add(1,2),因为 calculation 在您的程序中已不再被识别。原因是:一旦使用 as 为模块设置了别名,原名称在该脚本中将不再可用。
Python 中的模块搜索路径
您可能希望在不同的程序或项目中使用自己的模块,而它们在目录中的物理位置可能不同。如果要使用位于其他目录的模块,Python 提供了若干选项。
当您导入名为 calculation 的模块时,解释器会先搜索是否存在该名称的内置模块;如果没有,再在由变量 sys.path 指定的目录列表中搜索名为 calculation.py 的文件。sys.path 包含以下位置:
-
包含输入脚本的目录(或当前目录)
-
PYTHONPATH(与 shell 变量PATH语法相同的目录名列表) -
与安装相关的默认路径
假设 module_test.py 位于 /home/datacamp/ 目录,而您把 calculation.py 移动到了 /home/test/。您可以修改 sys.path,将 /home/test/ 加入到解释器搜索模块的路径列表中。为此,您需要按如下方式修改 module_test.py:
import sys
sys.path.append('/home/test/')
import calculation
print(calculation.add(1,2))
Python 中的字节码文件
导入模块会增加程序的执行时间,因此 Python 通过一些技巧来加速。其中一种方式是创建以 .pyc 为扩展名的字节码文件。
在内部,Python 会将源代码转换为称为字节码的中间形式,然后再将其翻译为计算机的本地语言并运行。下次从另一个程序导入该模块时,这个 .pyc 文件会派上用场——导入速度会更快,因为导入模块所需的部分处理工作已经完成。此外,这些字节码文件与平台无关。
注意,这些 .pyc 文件通常会在与相应 .py 文件相同的目录中创建。如果 Python 无权在该目录写文件,则不会创建 .pyc 文件。这些文件通常存放在 __pycache__ 目录中,和您的 .py 文件并列,文件名类似于 calculation.cpython-312.pyc,以反映所用的 Python 版本。您可以放心忽略该文件夹,或在 .gitignore 中排除它。Python 会自动管理它。
Python 的 dir() 函数
dir() 函数用于查看模块中定义的所有名称。它会返回一个排序后的字符串列表,包含模块中定义的名称。
import calculation
print(calculation.add(1,2))
print(dir(calculation))
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'add', 'sub']
在输出中,您可以看到在模块中定义的函数名 add 和 sub。属性 __name__ 包含模块的名称。所有以下划线开头的属性,都是与模块关联的 Python 默认属性。
结语
创建模块有助于更好地管理代码并提升复用性。Python 为您提供了一些内置模块,可通过 import 关键字导入。Python 也允许您创建自己的模块并在程序中使用。它通过字节码文件来降低使用模块的开销,从而加快执行速度。您可以使用 dir() 来了解程序中所用模块定义了哪些属性。该函数既可用于预定义模块,也可用于用户自定义模块。
如果您想要进一步学习 Python,欢迎查看我们的 数据科学进阶 Python 课程。
作者
Nishant Kumar
常见问答
我可以在函数内部导入模块吗?
可以。您可以在函数内部导入模块,但为了清晰与性能,通常最好在文件顶部进行导入。
如果两个模块同名会怎样?
Python 会按模块搜索路径(sys.path)中首先匹配到的进行导入。请注意命名以避免冲突。
我需要手动把模块编译成 .pyc 吗?
不需要。导入模块时,若具有写权限,Python 会自动创建 .pyc 文件。
使用 from module import * 可以吗?
可以用,但不推荐在生产代码中使用。它会污染命名空间,并使追踪实际使用的内容更加困难。
当您刚开始学习 Python 时,通常会把所有代码写在一个文件里。对于小脚本来说这没问题,但随着程序规模扩大,单文件会变得难读、难维护,也无法在不同项目间复用。Python 提供的解决方案就是模块。
在本教程中,您将了解什么是模块、如何导入模块、如何编写自己的模块,以及将入门脚本提升为生产级代码的最佳实践。在开始编写自己的模块之前,建议先学习我们的数据科学 Python 入门课程。
什么是 Python 模块?
模块本质上就是一个 Python 文件。任何带有
.py扩展名且包含 Python 代码(函数、类、变量或可运行逻辑)的文件,都是一个模块。当您保存一个名为calculation.py的文件时,您就创建了一个名为calculation的模块。模块的强大之处在于可以将其导入到其他程序中使用。与其把同一个函数复制粘贴到多个脚本里,不如在一个模块中定义一次,随后在需要时导入。这正是 Python 标准库的工作方式:它提供了许多预构建模块,如
math、os和random,您只需一行代码即可在任意程序中使用。更具体地说,在 Python 中您会遇到三类模块:
内置模块:随 Python 一起提供,例如我刚提到的
math和os。第三方模块:通过
pip安装,如numpy或pandas。您自己的模块:任何您自己编写的
.py文件。