ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Python 模块 > 原文: [http://zetcode.com/lang/python/modules/](http://zetcode.com/lang/python/modules/) 在 Python 教程的这一部分中,我们将使用 Python 模块。 几个示例说明了如何创建和使用 Python 模块。 模块是一个包含 Python 代码的文件。 Python 模块具有`.py`扩展名。 可以使用以下方法管理 Python 代码: * 函数 * 类 * 模组 * 包装 Python 模块用于组织 Python 代码。 例如,与数据库相关的代码位于数据库模块内部,安全代码位于安全模块中,等等。较小的 Python 脚本可以具有一个模块。 但是较大的程序分为几个模块。 模块组合在一起形成包装。 ## Python 模块名称 模块名称是带有`.py`扩展名的文件名。 当我们有一个名为`empty.py`的文件时,模块名称为空。 `__name__`是一个变量,其中包含要引用的模块的名称。 当前模块,正在执行的模块(也称为主模块)有一个特殊名称:`'__main__'`。 使用此名称,可以从 Python 代码中引用它。 当前工作目录中有两个文件:`empty.py`和`test_empty.py`。 第二个模块是执行的主模块。 导入第一个模块。 使用`import`关键字导入模块。 `empty.py` ```py """ An empty module """ ``` 这是`empty.py`模块。 `test_empty.py` ```py #!/usr/bin/env python import empty import sys print(__name__) print(empty.__name__) print(sys.__name__) ``` 在此代码示例中,我们导入两个模块:内置模块`sys`和一个自定义模块`empty`。 我们将模块的名称打印到控制台。 ```py $ ./test_empty.py __main__ empty sys ``` 正在执行的模块的名称始终为`'__main__'`。 其他模块以文件名命名。 可以使用`import`关键字将模块导入其他模块。 ## Python 定位模块 导入模块时,解释器首先搜索具有该名称的内置模块。 如果找不到,它将在变量`sys.path`给定的目录列表中搜索。 `sys.path`是一个字符串列表,用于指定模块的搜索路径。 它由当前工作目录,在`PYTHONPATH`环境变量中指定的目录名称以及一些其他与安装有关的目录组成。 如果找不到该模块,则会引发`ImportError`。 `locating_modules.py` ```py #!/usr/bin/env python import sys import textwrap sp = sorted(sys.path) dnames = ', '.join(sp) print(textwrap.fill(dnames)) ``` 该脚本从`sys.path`变量打印所有目录。 ```py import textwrap ``` `textwrap`模块用于轻松设置段落格式。 ```py sp = sorted(sys.path) ``` 我们从`sys.path`变量中检索目录列表并对它们进行排序。 ```py dnames = ', '.join(sp) ``` 我们从列表中取出一个字符串。 ```py $ ./locating_modules.py /home/janbodnar/.local/lib/python3.5/site-packages, /home/janbodnar/PycharmProjects/Simple, /home/janbodnar/PycharmProjects/Simple, /usr/lib/python3.5, /usr/lib/python3.5/lib-dynload, /usr/lib/python3.5/plat-x86_64-linux- gnu, /usr/lib/python3/dist-packages, /usr/lib/python35.zip, /usr/local/lib/python3.5/dist-packages ``` 这是一个示例输出。 ## Python `import`关键字 `import`关键字可以以多种方式使用。 ```py from module import * ``` 此构造会将所有 Python 定义导入另一个模块的名称空间。 有一个例外。 不导入以下划线字符`_`开头的对象。 预期它们只能由导入的模块在内部使用。 不建议使用这种方式导入模块。 `everything.py` ```py #!/usr/bin/python from math import * print(cos(3)) print(pi) ``` 此导入构造已从内置`math`模块导入了所有定义。 我们可以直接调用数学函数,而无需引用`math`模块。 ```py $ ./everything.py -0.9899924966004454 3.141592653589793 ``` 使用此导入构造可能会导致名称空间污染。 我们可能有多个同名的对象,并且它们的定义可以被覆盖。 `pollution.py` ```py #!/usr/bin/env python from math import * pi = 3.14 print(cos(3)) print(pi) ``` 该示例将在控制台上打印 3.14。 这可能不是我们想要的。 在大型项目中,命名空间污染可能变得至关重要。 ## 未导入的 Python 对象 以下示例显示了未使用此`import`构造导入的定义。 `names.py` ```py #!/usr/bin/env python """ names is a test module """ _version = 1.0 names = ["Paul", "Frank", "Jessica", "Thomas", "Katherine"] def show_names(): for i in names: print(i) def _show_version(): print(_version) ``` 这是`names.py`模块。 `test_names.py` ```py #!/usr/bin/env python from names import * print(locals()) show_names() ``` `_version`变量和`_show_version()`函数未导入到`test_names`模块中。 我们在命名空间中看不到它们。 `locals()`函数为我们提供了模块中所有可用的定义。 ## 导入特定对象 使用`from`和`import`关键字,可以仅导入某些对象。 ```py from module import fun, var ``` 此导入构造仅从模块导入特定对象。 这样,我们仅导入我们需要的定义。 `import_specific.py` ```py #!/usr/bin/python from math import sin, pi print(sin(3)) print(pi) ``` 我们从`math`模块导入两个对象。 我们无法引用其他定义(例如`cos`函数)。 `imnames.py` ```py #!/usr/bin/python from names import _version, _show_version print(_version) _show_version() ``` 我们也可以导入下划线开头的定义。 但这是一个不好的做法。 ```py $ ./imnames.py 1.0 1.0 ``` ## Python 导入模块 最后一种构造使用最广泛。 ```py import module ``` 它防止名称空间污染,并允许从模块访问所有定义。 `impmod.py` ```py #!/usr/bin/env python import math pi = 3.14 print(math.cos(3)) print(math.pi) print(math.sin(3)) print(pi) ``` 在这种情况下,我们通过模块名称引用定义。 如我们所见,我们可以使用两个`pi`变量。 我们的定义来自`math`模块。 ```py $ ./impmod.py -0.9899924966004454 3.141592653589793 0.1411200080598672 3.14 ``` ## Python 别名模块 我们可以使用`as`关键字为模块创建别名。 `importas.py` ```py #!/usr/bin/python # importas.py import math as m print(m.pi) print(m.cos(3)) ``` 我们可以更改引用模块的名称。 为此,我们使用`as`关键字。 ```py $ ./importas.py 3.14159265359 -0.9899924966 ``` ## `ImportError` 如果无法导入模块,则会引发`ImportError`。 `importerror.py` ```py #!/usr/bin/env python try: import empty2 except ImportError as e: print('Failed to import:', e) ``` 我们尚未创建`empty2`模块。 因此引发了异常。 ```py $ ./importerror.py Failed to import: No module named empty2 ``` 示例输出。 ## 执行 Python 模块 模块可以导入其他模块,也可以执行。 模块作者经常创建测试套件来测试模块。 仅当模块作为脚本执行时,`__name__`属性等于`'__main__'`。 我们将在斐波那契模块上对此进行演示。 斐波那契数是一个数字序列,其中每个数字都是其两个直接前辈的总和。 `fibonacci.py` ```py #!/usr/bin/env python """ A module containing the fibonacci function. """ def fib(n): a, b = 0, 1 while b < n: print(b, end=" ") (a, b) = (b, a + b) # testing if __name__ == '__main__': fib(500) ``` 通常可以照常导入该模块。 该模块也可以执行。 ```py $ ./fibonacci.py 1 1 2 3 5 8 13 21 34 55 89 144 233 377 ``` 如果确实导入了`fibonacci`模块,则不会自动执行测试。 ```py >>> import fibonacci as fib >>> fib.fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 ``` 导入了`fibonacci`模块,并执行了`fib()`函数。 ## Python `dir`函数 内置的`dir()`函数提供了包含模块定义名称的字符串排序列表。 `dirfun.py` ```py #!/usr/bin/env python """ This is dirfun module """ import math, sys version = 1.0 names = ["Paul", "Frank", "Jessica", "Thomas", "Katherine"] def show_names(): for i in names: print(i) print(dir()) ``` 在此模块中,我们导入两个系统模块。 我们定义一个变量,一个列表和一个函数。 ```py print(dir()) ``` `dir()`函数返回模块当前名称空间中所有可用的名称。 ```py $ ./dirfun.py ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'math', 'names', 'show_names', 'sys', 'version'] ``` 我们可以看到一些内置名称,例如`'__file__'`或`'__name__'`,以及我们定义和导入的所有其他名称。 ## Python 全局函数 `globals()`函数返回代表当前全局​​名称空间的字典。 它是全局名称及其值的字典。 它是当前模块的字典。 `globalsfun.py` ```py #!/usr/bin/env python import textwrap version = 1.0 def myfun(): pass gl = globals() gnames = ', '.join(gl) print(textwrap.fill(gnames)) ``` 我们使用`globals()`函数来打印当前模块的所有全局名称。 ```py $ ./globalsfun.py textwrap, __package__, version, __builtins__, __name__, __spec__, __doc__, gl, __cached__, myfun, __loader__, __file__ ``` 这些是当前模块的全局名称。 ## Python `__module__`属性 `__module__`类属性具有定义该类的模块的名称。 `animals.py` ```py """ module animals """ class Cat: pass class Dog: pass ``` 这是`animals.py`文件的内容。 我们有两个类。 `mclass.py` ```py #!/usr/bin/env python from animals import Cat class Being: pass b = Being() print(b.__module__) c = Cat() print(c.__module__) ``` 在此代码中,我们使用`__module__`属性。 ```py from animals import Cat ``` 从`animals`模块,我们导入`Cat`类。 ```py class Being: pass ``` 在当前模块中,我们定义一个类`Being`。 ```py b = Being() print(b.__module__) ``` 创建`Being`类的实例。 我们打印其模块的名称。 ```py c = Cat() print(c.__module__) ``` 我们从`Cat`类创建一个对象。 我们还将在定义模块的位置打印。 ```py $ ./mclass.py __main__ animals ``` 当前模块的名称为`'__main__'`。 `Cat's`模块的名称是动物。 本章是关于 Python 中的模块的。