The Python Tutorial 3.2-6Modules(模块)

来源:互联网 发布:无法无天吾知txt下载 编辑:程序博客网 时间:2024/05/16 19:54

6. Modules(模块)


If you quit from the Python interpreter and enter it again, the definitions you have made (functions and variables) are lost. Therefore, if you want to write a somewhat longer program, you are better off using a text editor to prepare the input for the interpreter and running it with that file as input instead. This is known as creating a script. As your program gets longer, you may want to split it into several files for easier maintenance. You may also want to use a handy function that you’ve written in several programs without copying its definition into each program.

如果你退出Python解释器并重新进入,你做的任何定义(函数和变量)都会丢失。因此,如果你想要编写一些更大的程序,为准备解释器输入使用一个文本编辑器会更好,并以那个文件替代作为输入执行。这就是传说中的脚本 。随着你的程序变得越来越长,你可能想要将它分割成多个文件便于更容易维护。你也可能想在不同的程序中使用一个手边的函数,而不是把代码复制到每个程序中。

To support this, Python has a way to put definitions in a file and use them in a script or in an interactive instance of the interpreter. Such a file is called a module; definitions from a module can be imported into other modules or into the main module (the collection of variables that you have access to in a script executed at the top level and in calculator mode).

为此,Python提供了一种将定义保存在一个文件中的方法,然后在脚本中或解释器的交互实例中使用。这个文件被称作模块 ,模块中的定义可以被导入到其他的模块或者main模块(你在顶层进入执行脚本或计算模式下的变量的集合)。

A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended. Within a module, the module’s name (as a string) is available as the value of the global variable __name__. For instance, use your favorite text editor to create a file called fibo.py in the current directory with the following contents:

模块就是一个包含Python定义和语句的文件。文件名就是模块名加.py扩展名。在一个模块中,模块的名字(字符串形式)通过全局变量 __name__ 获取。例如,用你喜欢的编辑器在当前目录下建立一个包含以下内容的 fibo.py 文件:

# Fibonacci numbers moduledef fib(n):    # write Fibonacci series up to n    a, b = 0, 1    while b < n:        print(b, end=' ')        a, b = b, a+b    print()def fib2(n): # return Fibonacci series up to n    result = []    a, b = 0, 1    while b < n:        result.append(b)        a, b = b, a+b    return result

Now enter the Python interpreter and import this module with the following command:

现在进入Python解释器并使用以下命令导入这个模块:

>>> import fibo

This does not enter the names of the functions defined in fibo directly in the current symbol table; it only enters the module name fibo there. Using the module name you can access the functions:

这并不会在当前符号表内直接引入 fibo 中定义的函数名,这里仅引入了 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'

If you intend to use a function often you can assign it to a local name:

如果打算经常使用一个函数,你可以将它赋予一个局部变量:

>>> fib = fibo.fib>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

6.1. More on Modules(深入模块)

A module can contain executable statements as well as function definitions. These statements are intended to initialize the module. They are executed only the first time the module is imported somewhere. [1]

除了包含函数定义外,模块也可以包含可执行语句。这些语句一般用来初始化模块。他们仅在某处被导入时第一时间执行。[2]

Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user’s global variables. On the other hand, if you know what you are doing you can touch a module’s global variables with the same notation used to refer to its functions, modname.itemname.

每个模块都有自己私有的符号表,被所有定义在模块内的函数作为全局符号表使用。因此,模块的作者可以在模块内部使用全局变量,而无需担心它与某个用户的全局变量意外冲突。从另一个方面讲,如果你确切的知道自己在做什么,你可以同样使用引用函数的方式来访问模块的全局变量, modname.itemname 。

Modules can import other modules. It is customary but not required to place all import statements at the beginning of a module (or script, for that matter). The imported module names are placed in the importing module’s global symbol table.

模块可以导入其他模块。一个惯例(非强制的)是将所有的 import 语句放在模块的开始(或者是脚本)。所有被导入的模块名会放入当前模块的全局符号表中。

There is a variant of the import statement that imports names from a module directly into the importing module’s symbol table. For example:

还有一种 import 语句的变体,可以从一个模块中将名字直接导入到当前模块的符号表中。例如:

>>> from fibo import fib, fib2>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

This does not introduce the module name from which the imports are taken in the local symbol table (so in the example, fibo is not defined).

这种方式不会把操作的模块名引入当前符号表中(所以在这个列子中, fibo 是未定义的)。

There is even a variant to import all names that a module defines:

甚至,还有一种变体用于导入模块中定义的所有名称:

>>> from fibo import *>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

This imports all names except those beginning with an underscore (_). In most cases Python programmers do not use this facility since it introduces an unknown set of names into the interpreter, possibly hiding some things you have already defined.

这会导入那些所有除了以下划线( _ )开头的名称。大多数情况,Python程序员不会使用这个技巧。因为它会向解释器引入一个未知的名称集合,很可能会将你已经定义的东西覆盖掉。

Note that in general the practice of importing * from a module or package is frowned upon, since it often causes poorly readable code. However, it is okay to use it to save typing in interactive sessions.

注意在一般从一个模块或包导入*的实践会引起人们的不满,因为这样会造成可读性差的代码。然而,它允许在交互式会话中使用以便节省输入

NoteFor efficiency reasons, each module is only imported once per interpreter session. Therefore, if you change your modules, you must restart the interpreter – or, if it’s just one module you want to test interactively, use imp.reload(), e.g. import imp; imp.reload(modulename).

出于效率原因,在一个解释器会话中每个模块仅被导入一次。所以,如果你修改了你的模块,你必须重启你的解释器——或者如果只是一个你想要交互测试的模块,使用 imp.reload() 方法。比如, import imp; imp.reload(modulename) 。

6.1.1. Executing modules as scripts(将模块作为脚本执行)

When you run a Python module with

python fibo.py 

the code in the module will be executed, just as if you imported it, but with the __name__ set to "__main__". That means that by adding this code at the end of your module:

当你使用以下方式来运行个模块时:

python fibo.py 

在模块中的代码将被执行,就像你导入它一样,但是__name__被设置为"__main__"。这意味着,在你的模块末尾添加如下的代码:

if __name__ == "__main__":    import sys    fib(int(sys.argv[1]))

you can make the file usable as a script as well as an importable module, because the code that parses the command line only runs if the module is executed as the “main” file:

你就可以让文件即是可导入的模块又是可用的脚本,因为这些解析命令行的代码仅当模块被当做“main”文件执行时才会被运行。

$ python fibo.py 501 1 2 3 5 8 13 21 34

If the module is imported, the code is not run:

如果这个模块是被导入的,这些代码("__main__"中的不会执行):

>>> import fibo>>>

This is often used either to provide a convenient user interface to a module, or for testing purposes (running the module as a script executes a test suite).

这种方式通常被用来为模块提供一个方便的用户接口,或者为了测试目的(将模块当做脚本一样运行,以便执行测试程序)

6.1.2. The Module Search Path(模块的搜索路径)

When a module named spam is imported, the interpreter searches for a file named spam.py in the directory containing the input script and then in the list of directories specified by the environment variable PYTHONPATH. This has the same syntax as the shell variable PATH, that is, a list of directory names. When PYTHONPATH is not set, or when the file is not found there, the search continues in an installation-dependent default path; on Unix, this is usually .:/usr/local/lib/python.

当一个名为 spam 的模块被导入时,解释器首先会在当前目录搜索一个名为 spam.py 的文件,然后是在环境变量 PYTHONPATH 中定义的目录列表继续搜索。这和shell变量 PATH 具有一样的语法,即一系列目录名的列表。如果没有定义 PYTHONPATH ,或者路径目录下没有找到文件,解释器会继续在Python默认安装路径中搜索。在Unix系统上,这通常是.:/usr/local/lib/python 。

Actually, modules are searched in the list of directories given by the variable sys.path which is initialized from the directory containing the input script (or the current directory), PYTHONPATH and the installation- dependent default. This allows Python programs that know what they’re doing to modify or replace the module search path. Note that because the directory containing the script being run is on the search path, it is important that the script not have the same name as a standard module, or Python will attempt to load the script as a module when that module is imported. This will generally be an error. See section Standard Modules for more information.

实际上,模块都是在变量 sys.path 定义的目录列表中查找,它是从包含输入脚本的目录(当前目录)、 PYTHONPATH 和Python默认安装目录初始而来。这允许那些确切知道在做什么的Python程序可以修改或替换模块搜索路径。注意:因为包含执行脚本的目录也在搜索路径中,所以重要的是脚本与Python标准模块不应该具有相同的名字,否则当导入一个模块时Python将会尝试把脚本当做模块加载。这通常会导致一个错误。更多信息请参考 Standard Modules 标准模块章节 。

6.1.3. “Compiled” Python files("被编译的"Python文件)

As an important speed-up of the start-up time for short programs that use a lot of standard modules, if a file called spam.pyc exists in the directory where spam.py is found, this is assumed to contain an already-“byte-compiled” version of the module spam. The modification time of the version of spam.py used to create spam.pyc is recorded in spam.pyc, and the .pyc file is ignored if these don’t match.

作为一个为使用大量标准模块的小程序启动时间加速的重要方式,如果在 spam.py 所在的目录存在一个名为 spam.pyc 的文件,这被认为是模块 spam 的“字节编译”版本。创建 spam.pyc 时文件 spam.py 的修改时间版本会被记录在 spam.pyc 文件中,如果这修改时间(.py的与.pyc中记录的)不一致,那么.pyc 文件就会被忽略。

Normally, you don’t need to do anything to create the spam.pyc file. Whenever spam.py is successfully compiled, an attempt is made to write the compiled version to spam.pyc. It is not an error if this attempt fails; if for any reason the file is not written completely, the resulting spam.pyc file will be recognized as invalid and thus ignored later. The contents of the spam.pyc file are platform independent, so a Python module directory can be shared by machines of different architectures.

通常,你无需自行创建 spam.pyc 文件。每次 spam.py 成功编译后,都会尝试将编译版本写入 spam.pyc 文件。如果尝试写入失败,也不会引发什么错误。不论什么情况,如果文件没有被正确写入,目标文件 spam.pyc 会被认为是无效的并且会被忽略。 spam.pyc 文件的内容是平台无关的,所以一个Python模块目录可以被不同体系架构的机器共享。

Some tips for experts:

一些专家提示:

  • When the Python interpreter is invoked with the -O flag, optimized code is generated and stored in .pyo files. The optimizer currently doesn’t help much; it only removes assert statements. When -O is used, all bytecode is optimized; .pyc files are ignored and .py files are compiled to optimized bytecode.
  • 当使用 -O 标志启动Python解释器时,Python会生成优化代码并存储在 .pyo 文件中。当前的优化器没有多大用处,只是去除 assert 语句。当使用 -O 时, 所有的bytecode 都会被优化; .pyc 文件被忽略并且.py 文件会被编译成优化的字节码。
  • Passing two -O flags to the Python interpreter (-OO) will cause the bytecode compiler to perform optimizations that could in some rare cases result in malfunctioning programs. Currently only __doc__ strings are removed from the bytecode, resulting in more compact .pyo files. Since some programs may rely on having these available, you should only use this option if you know what you’re doing.
  • 为Python解释器传递两个 -O 标志( -OO )将使字节码编译器执行尽可能的优化,这在少数情况下可能导致程序故障。目前只会将 __doc__ 字符串从字节码中移除,生成更紧凑的 .pyo 文件。虽然很多程序可能依赖这些有效的(优化),但你还是应该在确定的情况下使用这个选项。
  • A program doesn’t run any faster when it is read from a .pyc or .pyo file than when it is read from a .py file; the only thing that’s faster about .pyc or .pyo files is the speed with which they are loaded.
  • 程序不会因为从 .pyc 文件或 .pyo 文件中读取而比从 .py 文件中读取运行的更快。唯一提升的是他们的加载速度。
  • When a script is run by giving its name on the command line, the bytecode for the script is never written to a .pyc or .pyo file. Thus, the startup time of a script may be reduced by moving most of its code to a module and having a small bootstrap script that imports that module. It is also possible to name a .pyc or .pyo file directly on the command line.
  • 当从命令行通过指定文件名执行一个脚本时,脚本的字节码不会被写到 .pyc 或 .pyo 文件中。因此,通过将大多数代码放进一个模块,并使用一个导入此模块的引导脚本可能会减少脚本的启动时间。也可以在命令行中直接命名 .pyc 或 .pyo 文件。
  • It is possible to have a file called spam.pyc (or spam.pyo when -O is used) without a file spam.py for the same module. This can be used to distribute a library of Python code in a form that is moderately hard to reverse engineer.
  • 同一模块还可以只有 spam.pyc 文件(或者 spam.pyo ,当使用 -O 时)而没有 spam.py 文件。这可以作为发布Python代码库的形式,使反向工程更困难
  • The module compileall can create .pyc files (or .pyo files when -O is used) for all modules in a directory.
  • compileall 模块可以将同一目录中的所有模块编译成 .pyc 文件(或者 .pyo 文件,当使用 -O 时)。

6.2. Standard Modules(标准模块)

Python comes with a library of standard modules, described in a separate document, the Python Library Reference (“Library Reference” hereafter). Some modules are built into the interpreter; these provide access to operations that are not part of the core of the language but are nevertheless built in, either for efficiency or to provide access to operating system primitives such as system calls. The set of such modules is a configuration option which also depends on the underlying platform For example, the winreg module is only provided on Windows systems. One particular module deserves some attention: sys, which is built into every Python interpreter. The variables sys.ps1 and sys.ps2 define the strings used as primary and secondary prompts:

Python伴随了一个标准模块库,在独立的Python库参考文档中描述(即后面的“库参考文档”)。有些模块内置在解释器里,这些或者为效率或者为支持类似系统调用等系统级访问控制提供了操作入口,虽然他们不是语言核心的组成部分但仍然是内置的。这些模块会根据底层平台进行不同的选择配置,比如 winreg 模块只在Windows系统上提供。有一个特别的模块应该注意: sys ,它内置在每个Python解释器中。变量 sys.ps1 和 sys.ps2 分别定义了主提示符和次提示符使用的字符串。

>>> import sys>>> sys.ps1'>>> '>>> sys.ps2'... '>>> sys.ps1 = 'C> 'C> print('Yuck!')Yuck!C>

These two variables are only defined if the interpreter is in interactive mode.

这两个变量仅在解释器处于交互模式下被定义。

The variable sys.path is a list of strings that determines the interpreter’s search path for modules. It is initialized to a default path taken from the environment variable PYTHONPATH, or from a built-in default if PYTHONPATH is not set. You can modify it using standard list operations:

变量 sys.path 是一个字符串列表,决定了解释器搜索模块的路径。如果定义了环境变量 PYTHONPATH ,它将以此初始化默认路径,否则就使用一个内置的默认值。你可以使用标准的列表操作符来修改这个值。

>>> import sys>>> sys.path.append('/ufs/guido/lib/python')

6.3. The dir() Function

The built-in function dir() is used to find out which names a module defines. It returns a sorted list of strings:

>>> import fibo, sys>>> dir(fibo)['__name__', 'fib', 'fib2']>>> dir(sys)['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'callstats', 'copyright', 'displayhook', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags', 'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version', 'version_info', 'warnoptions']

Without arguments, dir() lists the names you have defined currently:

如果没有指定参数,dir()列出当前用户定义的所有名称:

>>> a = [1, 2, 3, 4, 5]>>> import fibo>>> fib = fibo.fib>>> dir()['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys']

Note that it lists all types of names: variables, modules, functions, etc.

注意它列表出了所有类型的名称:变量,模块,函数等.

dir() does not list the names of built-in functions and variables. If you want a list of those, they are defined in the standard module builtins:

dir()不会列出内置函数和变量的名称。如果你想列表这些,它们都被定义在标准的builtins模块中:

>>> import builtins>>> dir(builtins)['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any','ascii', 'bin', 'bool', 'bytearray', 'bytes', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr','globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

6.4. Packages(包)

Packages are a way of structuring Python’s module namespace by using “dotted module names”. For example, the module name A.B designates a submodule named B in a package named A. Just like the use of modules saves the authors of different modules from having to worry about each other’s global variable names, the use of dotted module names saves the authors of multi-module packages like NumPy or the Python Imaging Library from having to worry about each other’s module names.

包是通过使用“点缀模块名称”创建Python模块命名空间的一种方法。列如,模块名称 A.B 表示一个在名为 A 的包下的名为 B 的子模块。就像使用模块让不同模块的作者无需担心彼此全局变量名称(冲突)一样,点缀模块名称让多模块包的作者无需担心彼此的模块名称(冲突),像NumPy或Python图像库。

Suppose you want to design a collection of modules (a “package”) for the uniform handling of sound files and sound data. There are many different sound file formats (usually recognized by their extension, for example: .wav, .aiff, .au), so you may need to create and maintain a growing collection of modules for the conversion between the various file formats. There are also many different operations you might want to perform on sound data (such as mixing, adding echo, applying an equalizer function, creating an artificial stereo effect), so in addition you will be writing a never-ending stream of modules to perform these operations. Here’s a possible structure for your package (expressed in terms of a hierarchical filesystem):

假设,你想设计一系列模块(一个“包”)用于统一处理声音文件和声音数据。现在有很多不同的声音文件格式(通常以他们的扩展名区分,例如:.wav,.aiff,.au),所以你可能需要创建并维护一个不断增长的模块集用于不同文件格式间转换。还可能有很多你想用来处理声音数据的不同操作,比如:混音,添加回声,应用均衡器,创建人造立体声等。因此,为了完成这些操作你还需要另外编写一个永远也完不成的模块。这里是你的包的一种可能的结构(用层级文件系统表示)。

sound/                          Top-level package      __init__.py               Initialize the sound package      formats/                  Subpackage for file format conversions              __init__.py              wavread.py              wavwrite.py              aiffread.py              aiffwrite.py              auread.py              auwrite.py              ...      effects/                  Subpackage for sound effects              __init__.py              echo.py              surround.py              reverse.py              ...      filters/                  Subpackage for filters              __init__.py              equalizer.py              vocoder.py              karaoke.py              ...

When importing the package, Python searches through the directories on sys.path looking for the package subdirectory.

当导入这个包时,Python通过 sys.path 搜索路径查找包含这个包的子目录。

The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later.

为了让Python将目录当做内容包,目录中必须包含 __init__.py 文件。这是为了避免一个使用普通名字的目录无意中隐藏了稍后在模块搜索路径中出现的有效模块,比如 string 。最简单的情况下,只需要一个空的 __init__.py 文件即可。当然它也可以执行包的初始化代码,或者定义稍后介绍的 __all__ 变量。

Users of the package can import individual modules from the package, for example:

用户可以每次只导入包里的特定模块,例如:

import sound.effects.echo

This loads the submodule sound.effects.echo. It must be referenced with its full name.

这会加载 sound.effects.echo 子模块。你必须使用它的全名来引用。

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

An alternative way of importing the submodule is:

导入子模块的一种可替换的方法:

from sound.effects import echo

This also loads the submodule echo, and makes it available without its package prefix, so it can be used as follows:

这同样会加载 echo 子模块,并使它无需使用包前缀即可使用,如下所示:

echo.echofilter(input, output, delay=0.7, atten=4)

Yet another variation is to import the desired function or variable directly:

还有另一种变化就是可以直接导入想要的变量或函数:

from sound.effects.echo import echofilter

Again, this loads the submodule echo, but this makes its function echofilter() directly available:

再次,这会加载 echo 子模块,但这使它的函数 echofilter() 可以直接使用。

echofilter(input, output, delay=0.7, atten=4)

Note that when using from package import item, the item can be either a submodule (or subpackage) of the package, or some other name defined in the package, like a function, class or variable. The import statement first tests whether the item is defined in the package; if not, it assumes it is a module and attempts to load it. If it fails to find it, an ImportError exception is raised.

注意:当使用 from package import item 时, item 既可以是包的子模块(或子包),也可以是包中定义的其他名称,比如函数、类或变量。 import 语句首先检查包中是否定义了 item ,如果没有它就假设这是一个模块并尝试加载它。如果没有找到这个模块,就会抛出一个 ImportError 异常。

Contrarily, when using syntax like import item.subitem.subsubitem, each item except for the last must be a package; the last item can be a module or a package but can’t be a class or function or variable defined in the previous item.

相反的,当使用 import item.subitem.subsubitem 语法时,除了最后一项外所有的项必须是一个包。最后一项可以是一个模块或包,但不能是其前面项定义的一个类、函数或变量。

6.4.1. Importing * From a Package(从一个包中导入*)

Now what happens when the user writes from sound.effects import *? Ideally, one would hope that this somehow goes out to the filesystem, finds which submodules are present in the package, and imports them all. This could take a long time and importing sub-modules might have unwanted side-effects that should only happen when the sub-module is explicitly imported.

现在当用户写下from sound.effects import *时会发生什么?理想情况下,人们期望这会以某种方式友好的对待文件系统,查看出在包中出现的子模块,并且将它们全部导入。这将花费很长的时间,子模块的导入可能产生不好的副作用,所以子模块的导入应该仅在当子模块被明确导入时才发生。

The only solution is for the package author to provide an explicit index of the package. The import statement uses the following convention: if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered. It is up to the package author to keep this list up-to-date when a new version of the package is released. Package authors may also decide not to support it, if they don’t see a use for importing * from their package. For example, the file sounds/effects/__init__.py could contain the following code:

唯一的解决办法就是由包作者为包提供一个精确的索引。导入语句会使用如下的转换规则:如果包文件 __init__.py 代码中定义了一个名为 __all__ 的列表,当使用 from package import * 时它被当做应该被导入的模块名称的列表。当发布包的一个新版本时,应该由包作者负责保持这个列表是最新的。如果包作者在包中没有发现导入*的用法,那么他们也可以决定不去做这些。例如, sounds/effects/__init__.py 文件可以包含如下代码:

__all__ = ["echo", "surround", "reverse"]

This would mean that from sound.effects import * would import the three named submodules of the sound package.

这意味着 from sound.effects import * 将会从 sound 包中导入三个指定的子模块。

If __all__ is not defined, the statement from sound.effects import * does not import all submodules from the package sound.effects into the current namespace; it only ensures that the package sound.effects has been imported (possibly running any initialization code in __init__.py) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by __init__.py. It also includes any submodules of the package that were explicitly loaded by previous import statements. Consider this code:

如果没有定义 __all__ , from sound.effects import * 语句不会从 sound.effects 包中将其所有的子模块导入到当前命名空间。它只会确定 sound.effects 包已经被导入(可能是通过执行 __init__.py 文件中的某段初始化代码),然后导入包中定义的任何名称。这包含 __init__.py 文件中定义的任何名称(和明确加载的模块)。它也包含通过前面import语句明确加载在包中的任何模块。思考以下代码:

import sound.effects.echoimport sound.effects.surroundfrom sound.effects import *

In this example, the echo and surround modules are imported in the current namespace because they are defined in the sound.effects package when the from...import statement is executed. (This also works when __all__ is defined.)

在这个示例中, echo 和 surround 模块被导入到当前命名空间,因为当 from...import 语句执行时它们就通过 sound.effects` 包被定义。(同样可以通过定义 __all__ 来做到这一点。)

Although certain modules are designed to export only names that follow certain patterns when you use import *, it is still considered bad practise in production code.

当你使用import *时,虽然某些模块被设计用来导出仅仅遵循某些模式的名称,但它仍然是一个在产品代码中糟糕的实践

Remember, there is nothing wrong with using from Package import specific_submodule! In fact, this is the recommended notation unless the importing module needs to use submodules with the same name from different packages.

记住,使用 from package import specific_submodule 永远不会有错!事实上,这是被推荐使用的方法,除非从不同包中导入的子模块使用了相同的名字。

6.4.2. Intra-package References(包内引用)

When packages are structured into subpackages (as with the sound package in the example), you can use absolute imports to refer to submodules of siblings packages. For example, if the module sound.filters.vocoder needs to use the echo module in the sound.effects package, it can use from sound.effects import echo.

当包被组织成子包时(就像示例中的 sound 包),你可以使用绝对导入来引用兄弟包的子模块。例如,如果 sound.filter.vocoder 模块需要使用 sound.effects 包中的 echo 模块,可以使用 from sound.effects import echo 。

You can also write relative imports, with the from module import name form of import statement. These imports use leading dots to indicate the current and parent packages involved in the relative import. From the surround module for example, you might use:

你也可以通过 from module import name 导入语句方式编写相对导入。在相对导入中,通过使用前导点号来表示是从当前包或是父包中导入。列如,从 surround 包中你可以使用:

from . import echofrom .. import formatsfrom ..filters import equalizer

Note that relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application must always use absolute imports.

6.4.3. Packages in Multiple Directories(多级目录中的包)

Packages support one more special attribute, __path__. This is initialized to be a list containing the name of the directory holding the package’s __init__.py before the code in that file is executed. This variable can be modified; doing so affects future searches for modules and subpackages contained in the package.

包还支持一个特殊的属性: __path__ 。它在__init__.py执行之前被初始化为包含包文件 __init__.py 的目录名字的列表。你可以修改这个变量,用来影响对包含在包中的子包和模块的搜索。

While this feature is not often needed, it can be used to extend the set of modules found in a package.

尽管这个特性并不常用,但它可以用来扩展一个包中的模块集合。

Footnotes(脚注)

[1] In fact function definitions are also ‘statements’ that are ‘executed’; the execution of a module-level function enters the function name in the module’s global symbol table.

[1]实际上,函数定义也是'可执行'的 '语句' ,模块级函数的执行将函数名称放置到模块的全局符号表中。

原创粉丝点击