# 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`关键字可以以多种方式使用。

```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 中的模块的。