模块
模块就是包含 Python 定义和语句的文件. 文件的名字就是这个模块名再加上 .py
. 在一个模块中, 模块的名字 (一个字符串) 可以通过全局变量 __name__
得到.
创建一个名为 fibo.py
的文件, 并输入以下内容:
# Fibonacci 数列模块def fib(n): # 打印小于 n 的 Fibonacci 数列 a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a+b print()def fib2(n): # 返回小于 n 的 Fibonacci 数列 result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result
访问模块中的函式(这样并不会把 fibo
中定义的函式名 导入(import)
到当前的符号表里; 它只导入了模块名 fibo
. 你可以使用模块名来访问函式)
>>> import fibo>>> fibo.fib(1000)1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987>>> fibo.fib2(100)[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]>>> fibo.__name__'fibo'
模块不仅包含函式定义, 还可以包含可执行的语句. 这些语句一般用以初始化模块. 他们仅在模块 第一 次被导入时才被执行.
模块中可以导入其它的模块. 习惯上把 语句放在一个模块 (或者脚本, ) 的最开始, 当然这只是惯例不是强制的. 被导入模块的名称被放入当前模块的全局符号表里.
语句这有一种不同用法, 它可以直接把一个模块内(函式,变量)名称导入当前模块符号表里. 例如:
>>> from fibo import fib, fib2>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377
这样不会导入相应的模块名 (在这个例子里, fibo
并没有被定义).
还有一种方法可一次性导入模块中所有的名字定义:
>>> from fibo import *>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377
这样可以导入除以下划线开头 (_
) 的所有名字. 多数情况中, Python 程序员不使用这个窍门, 因为它导入了一些未知的名字到解释器里, 因此可能会意外重载一些你已经定义的东西.
把模块当成脚本来使用
模块有一些内置属性,用于完成特定的任务,如__name__、__doc__。每个模块都有一个名称。
例如:
__name__用于判断当前模块是否是程序的入库,如果当前程序正在被使用,__name__的值为“__main__”。通常给每个模块都添加一个条件语句,用于单独测试该模块的功能。
当你以如下方式运行一个 Python 模块时
python fibo.py
模块中的代码就会被执行, 就像被导入时一样, 但 __name__
被设为 "__main__"
. 这就意味着通过在模块最后加入以下代码:
if __name__ == "__main__": import sys fib(int(sys.argv[1]))
导入包
包就是一个完成特定任务的工具箱,为了实现程序的重用。把实现一个常用功能的代码组合到一个包中,调用包提供的服务从而实现重用。Python提供了许多有用的工具包,如字符串处理、图形用户接口、Web应用、图形图像处理等。这些自带的工具包和模块安装在Python的安装目录下的Lib子目录中。
包必须至少含有一个__int__.py文件按,该文件的内容可以为空。__int__.py用于标识当前文件夹是一个包。
导入模块
可以通过sys.path语句搜索模块的查找路径。当Python导入一个模块时,Python首先查找当前路径,然后查找lib目录、site-packages目录(Python\Lib\site-packages)和环境变量PATHONPATH设置的目录。如果导入的模块没有找到,手动在以上路径搜索一下是否含有这个模块。
导入包的常用方式
导入子模块
from sound.effects import echo
可以这样使用
echo.echofilter(input, output, delay=0.7, atten=4)
或者直接导入想要的函式或变量:
from sound.effects.echo import echofilter
* 注意: Python中的import语句比Java的import语句更加灵活。Python的import语句可以置于程序中任意的位置,甚至可以放在条件语句中。
从包中导入 *
当开发者写下 from sound.effects import *
会发生什么?
理想地, 我们期望程序会以以某种方法进入文件系统, 寻找在指定的包文件中,找到所有子模块, 并把它们全部导入. 这可能花费很长的时间, 而且对子模块进行显式导入时,还可能引发非期待的 副作用!
对于包作者, 唯一解决方案是提供包的显式索引. 语句有以下约定:
- 如果一个包的
__init__.py
代码定义了一个名为__all__
的列表, - 当遇到
from package import *
时, 它被用来作为导入的模块名字的列表.
例如, 文件 sound/effects/__init__.py
可能包含如下代码
__all__ = ["echo", "surround", "reverse"]
这意味这 from sound.effects import *
将导入 sound
中这几个名字的子模块.
如果 __all__
没有被定义, from sound.effects import *
语句 不 把包 sound.effects
中所有的子模块都导入到当前命名空间里。它只能确保包 sound.effects
被导入了 (可能同时运行在 __init__.py`
里的一些初始化代码), 并随后导入包中定义的任何名字. 这包含任何在 __init__.py
定义的 任何名字 (和显式载入的子模块). 它还包含通过前面的 语句显式载入的包的子模块. 考虑这段代码:
import sound.effects.echoimport sound.effects.surroundfrom sound.effects import *
在这个例子中, 模块 echo
和 surround
被导入到当前命名空间, 因为当 执行 from...import
语句时它们就被定义在包 sound.effects
里. (当定义 __all__
定义时, 这也会工作.)
虽然有些模块被设计成当使用 import * 时仅导出遵循特定模式的名称, 但是在产品代码中仍然感觉算糟糕实践.
记住, 使用 from Package import specific_submodule 是没有问题的! 事实上, 这是推荐的用法, 只在以下情况例外: 正在导入的模块需要使用的子模块与其他包中的子模块具有相同的名字.
相对包导入
你还可以使用相对导入, 通过 import 语句的 from module import name
格式. 这些导入使用句点来表明涉及这次相对导入的当前包和父包. 从例子中的 surround
, 您可以使用
from . import echofrom .. import formatsfrom ..filters import equalizer
注意, 相对导入基于当前模块的名字. 因为主模块的名字总是 "__main__"
, 有意用作一个 Python 程序的主模块的模块必须总使用 绝对导入
.