模块
如果你从 Python 解释器退出然后再进入它,你所做的定义(函数和变量)都会消失。因此,如果你想写某些更长的程序,你最好使用一个文本编辑器来为解释器准备输入,然后以这个文件作为输入来运行程序。这也被称为创建一个 脚本。当你的程序变得更长,你也许会想将它分成几个文件方便管理。你也许还想在几个程序中直接使用函数而不用在每个程序中拷贝函数定义。
为了支持这种特性,Python 可以把定义放入一个文件中然后在一个脚本或交互式解释器实例中使用它。这个文件被叫做 模块 (module),模块中的定义可以通过 导入 进入到其他模块或者 主 模块(你在顶层和计算器模式下执行的脚本中可以访问的变量集合)。
一个模块是一个包含 Python 定义和声明的文件。文件是模块名加上 .py 后缀。在一个模块中,模块名(字符串类型)可以通过全局变量 __name__ 获取。例如,使用你最喜欢的文本编辑器在当前目录下创建一个叫 fibo.py 的文件,这个文件包含以下内容
# 斐波那契数模块
def fib(n): # 打印斐波那契数直到 n
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # 返回到 n 的斐波那契数
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
现在进入 Python 解释器然后通过下面的命令导入这个模块
>>> import fibo
这样做不会直接在当前环境中导入 fibo 中定义的函数名,只会导入名为 fibo 的模块。使用模块名可以获取模块中定义的函数:
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
如果你打算经常使用一个函数,你可以把它赋值给一个局部变量
>>> fib = fibo.fib
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
模块进阶
一个模块可以包含可执行声明包括函数定义。这些声明被用于初始化模块。它们只在模块被 第一 次导入时执行。 [1](如果文件被作为脚本运行它们也会被执行)
每个模块都有其私有的符号表,模块中定义的所有函数将这个符号表作为全局符号表。因此,一个模块的作者可以在模块中使用全局变量而无需担心与其他模块的全部变量冲突。另一方面,如果你知道你在干什么,你同样可以使用 模块.变量 的方式来获取一个模块的全局变量。
模块可以导入其他模块。将所有 import 语句放在模块(或者脚本,如果这个问题重要的话)的开头不是必须的,但习惯如此。被导入的模块名被放置于当前模块的全局符号表中。
import 声明的一种变体可以把一个模块中的变量直接导入当前模块的符号表中。例如:
>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
这样做不会把模块名引入本地符号表中(因此上面的例子里,fibo 没有被定义)
还有一种导入声明的变体可以导入一个模块中定义的所有变量:
>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
这会导入模块中除了以下划线(_)开头的所有名称。大多数情况下 Python 程序员不使用这个机制,因为它会为解释器引入一系列位置未知变量,从而有可能覆盖你已经定义的某些变量。
请注意,一般来说,使用 import * 导入模块或包是不受欢迎的,因为这通常会降低代码可读性。但在使用交互型解释器为了减少打字而使用它是允许的。
如果模块名后紧跟 as, 那么 as 后的变量名会与被导入的模块名绑定。
>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
这与 import fibo 的方式导入相同,除了模块现在被命名为 fib 而不是 fibo。
使用 from 时可以使用这个机制达到相同的效果:
模块搜索路径
当一个名为 spam 的模块被导入时,解释器首先寻找同名的内建模块。如果没有发现同名内建模块,解释器会根据 sys.path 提供的一系列路径下寻找名为 spam.py 的文件。sys.path 根据下面这些位置进行初始化:
包含输入脚本的目录(如果没有指明文件则为当前目录)
PYTHONPATH 一个目录的列表,语法与 shell 的 PATH 变量相同。
安装依赖默认路径。