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有一个方法可以把定义放在一个文件中,然后在脚本或解释器交互地调用它。这样的文件称作模块。模块中的定义可以被 import 导入到其他模块或模块(你在顶级和计算模式下执行的脚本中可以访问的变量集合)。

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 module

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

def fib2(n):   # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while a < n:
        result.append(a)
        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)
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'

If you intend to use a function often you can assign it to a local name:
如果你想要经常使用函数,你可以将其赋值给一个局部变量:

>>> fib = fibo.fib
>>> fib(500)
0 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 name is encountered in an import statement. [1] (They are also run if the file is executed as a script.)
一个模块可以包含执行语句和函数定义。这些语句可以初始化模块。它们只在模块的名字第一次出现导入语句时执行。(当这个文件被当做脚本运行时,它们也会被执行。)

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 importstatements 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)
0 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:
甚至还有一个import导入的变体来导入模块定义的所有名称:

>>> from fibo import *
>>> fib(500)
0 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.
请注意,普通情况下从一个模块或包中导入*是不受欢迎的,因为它经常使代码的可读性变得很差。但是,在交互式环节中为了减少输入是可以的。

If the module name is followed by as, then the name following as is bound directly to the imported module.
如果模块的名字后面跟着as,那么as后面的名字就直接跟导入的模块绑定在一起。

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

This is effectively importing the module in the same way that import fibo will do, with the only difference of it being available as fib.
这实际上是以“import fibo”的方式导入模块,唯一的区别在于它可以作为fib使用。

It can also be used when utilising from with similar effects:
当使用from时同样也可以使用,效果一样:

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

Note :For 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 importlib.reload(), e.g.import importlib; importlib.reload(modulename).
注意:为了效率的原因,每一个交互式会话中每个模块只需要被导入一次。因此,如果你要改变你的模块,你必须重启解释器,或者如果仅仅想要改变一个模块,可以使用importlib.reload().例如:

import importlib
importlib.reload(modulename)

6.1.1. Executing modules as scripts 像脚本一样执行模块

When you run a Python module with
当你运行一个Python脚本:

python fibo.py <arguments>

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:
模块中的代码将会被执行,就跟你导入它一样,把__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:
您可以使该文件可用作脚本以及可导入模块,因为命令行解析的代码仅在模块作为“主”文件执行时才会运行:

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

If the module is imported, the code is not run:
如果模块被导入,代码不会运行:

>>> 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 first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
当一个叫做spam的模块被导入,解释器首先用搜索是否内为置模块。如果没有找到,就会在系统变量sys.path中的列表中查找。sys.path初始化为下面的位置:

  • The directory containing the input script (or the current directory when no file is specified).
    输入脚本所在的目录(当没有文件指定时,取当前目录)
  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
    PYTHONPATH(目录名列表,语法与shell变量PATH相同)
  • The installation-dependent default.
    安装依赖的默认值。

Note:On file systems which support symlinks, the directory containing the input script is calculated after the symlink is followed. In other words the directory containing the symlink is not added to the module search path.
注意:在支持符号链接的文件系统上,包含输入脚本的目录是计算符号链接后面的。换句话说,包含符号链接的目录不会添加到模块搜索路径中。

After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended. See section Standard Modules for more information.
初始化之后,Python程序员可以修改sys.path.包含执行脚本的目录放在搜索路径的开始,在标准库路径前面。这意味着将加载该目录中的脚本,而不是库目录中的同名模块。除非有意更换,否则这是一个错误。

6.1.3. “Compiled” Python files 编译Python文件

To speed up loading modules, Python caches the compiled version of each module in the __pycache__ directory under the name module.*version*.pyc, where the version encodes the format of the compiled file; it generally contains the Python version number. For example, in CPython release 3.3 the compiled version of spam.py would be cached as __pycache__/spam.cpython-33.pyc. This naming convention allows compiled modules from different releases and different versions of Python to coexist.
为了快速加载模块,Python在module.*version*.pyc下面的__pycache__目录中为每一个模块缓存了编译的版本,按照编译文件的版本编码格式;它通常包含Python版本号。例如:在CPython发行版本3.3中spam.py的编译版本将会缓存在__pycache__/spam.cpython-33.pyc.这样命名的惯例允许Python中不同的发行和不同版本的编译能够共存。

Python checks the modification date of the source against the compiled version to see if it’s out of date and needs to be recompiled. This is a completely automatic process. Also, the compiled modules are platform-independent, so the same library can be shared among systems with different architectures.
Python 检查源文件和编译版本的修改日期来判断是否过期而需要重新编译。这个是全自动的进程。同样,已编译的模块是平台独立的,所有同样的库可以在不同体系架构的操作系统中共享。

Python does not check the cache in two circumstances. First, it always recompiles and does not store the result for the module that’s loaded directly from the command line. Second, it does not check the cache if there is no source module. To support a non-source (compiled only) distribution, the compiled module must be in the source directory, and there must not be a source module.
Python在两种情况下不会检查缓存:第一,从命令行直接导入的模块总是重新编译而不会储存结果。第二,如果没有源模块,它也不会检查缓存。为了支持非源(仅编译)分发,已编译模块必须在源目录中,并且不得有源模块。

Some tips for experts:
专家提示:

  • You can use the -O or -OO switches on the Python command to reduce the size of a compiled module. The -O switch removes assert statements, the -OO switch removes both assert statements and doc strings. Since some programs may rely on having these available, you should only use this option if you know what you’re doing. “Optimized” modules have an opt- tag and are usually smaller. Future releases may change the effects of optimization.
    你可以在Python命令中使用-O 或者 -OO开关来减少已编译模块的大小。 -O开关移除断言语句,-OO 开关移除断言语句和__doc__文档字符串。由于某些程序可能依赖于这些才可用,因此只有知道自己在做什么才能使用此选项。“优化”模块有一个'opt -`标签,通常更小。未来版本可能会改变优化的效果。

  • A program doesn’t run any faster when it is read from a .pyc file than when it is read from a .py file; the only thing that’s faster about .pyc files is the speed with which they are loaded.
    一个重新从.pyc读取并不会比从.py文件中读取运行的快。从.pyc中读取唯一快的一点就是他们加载的速度。

  • The module compileall can create .pyc files for all modules in a directory.
    compileall 模块可以为目录中的所有模块创建.pyc文件。

  • There is more detail on this process, including a flow chart of the decisions, in PEP 3147.
    有关此过程的更多详细信息,包括决策的流程图,尽在PEP 3147.

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 variablessys.ps1 and sys.ps2 define the strings used as primary and secondary prompts:
Python附带了一个标准模块库,在单独的文档:Python库参考(以下称为“库参考”)中进行了描述。一些模块是在解释器中内置的。这些操作提供对不属于语言核心但仍然内置的操作的访问,以提高效率或提供对系统调用等操作系统原语的访问。这些模块的集合是一个配置选项,它也取决于底层平台。例如:winreg模块只在windows系统中提供。有一个特殊的模块值得关注:sys模块,内置在每一个Python解释器中。 变量 sys.ps1sys.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的默认路径,如果PYTHONPATH没有设置,就取内置的默认值。你可以使用标准列表操作来操作它:

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

6.3. The dir() Function dir() 函数

The built-in function dir() is used to find out which names a module defines. It returns a sorted list of strings:
内置函数dir() 用来找出模块定义的名称。它返回一个有序的字符串列表:

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
 '__package__', '__stderr__', '__stdin__', '__stdout__',
 '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
 '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
 'call_tracing', 'callstats', 'copyright', 'displayhook',
 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
 'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
 'thread_info', '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__', '__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',
 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
 'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',
 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
 'NotImplementedError', 'OSError', 'OverflowError',
 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
 'SystemExit', 'TabError', 'TimeoutError', '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', 'callable',
 '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 Bin 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 Pillow from having to worry about each other’s module names.
包是一种使用“点模块名称”来构造Python模块命名空间的方法。例如,“A.B”表示在名为“A”的包中指定名为“B”的子模块。就像模块的使用一样,使不同模块的作者不必担心彼此的全局变量名称,使用点模块名称可以使NumPy或Pillow等多模块软件包的作者从彼此的模块名称的担心中解救出来。

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.pathlooking 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.
需要__init __.py文件才能使Python将目录视为所包含的包;这样做是为了防止具有通用名称的目录(例如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时,该项可以是包的子模块(或子包),也可以是包中定义的其他名称,如函数,类或变量。 import语句首先测试是否在包中定义了该项;如果没有,它假定它是一个模块并尝试加载它。如果找不到,则引发[ImportError 导入错误](https://docs.python.org/3/library/exceptions.html#ImportError“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__.pycode 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 sound/effects/__init__.pycould contain the following code:
唯一的解决方案是让包作者提供包的显式索引。 [import](https://docs.python.org/3/reference/simple_stmts.html#import)语句使用以下约定:如果包的__init __.py 代码定义了名为__all__的列表,它被视为遇到from package import *时应导入的模块名列表。在发布新版本的软件包时,由软件包作者决定是否保持此列表的最新状态。如果包作者没有看到从包中导入*的用法,他们也可能决定不支持它。例如,文件sound / 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 notimport 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](https://docs.python.org/3/reference/simple_stmts.html#import)语句显式加载的包的任何子模块。考虑以下代码:

import sound.effects.echo
import sound.effects.surround
from 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.)
在这个例子中,echosurround模块在当前命名空间中导入,因为在执行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 practice 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 packages 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.filters.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:
您还可以使用import语句的“from module import name”形式编写相对导入。这些导入使用点来指示相对导入中涉及的当前和父包。例如,从surround 模块,您可以使用:

from . import echo
from .. import formats
from ..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.
请注意,相对导入基于当前模块的名称。由于主模块的名称始终为“__ main __”,因此用作Python应用程序主模块的模块必须始终使用绝对导入。

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__](https://docs.python.org/3/reference/import.html#path“__ path__”)。这被初始化为一个列表,其中包含在执行该文件中的代码之前保存包的__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 definition enters the function name in the module’s global symbol table.
实际上,函数定义也是“执行”的“语句”;模块级函数定义的执行会在模块的全局符号表中输入函数名。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容

  • 算了下,年后生病到现在,没有持续地书写。好像总在等待一个心理舒服的时间才想写,于是搬家、收拾、爸妈在等等都成了一个...
    Stormy阅读 197评论 0 1
  • clfcool阅读 138评论 0 2
  • 用婴儿最初的方式哽咽 我仅凭着微弱的灯光 像个孩子不停的奔跑。 以为自己活的很高傲 开怀是一张没有来支透的钞票。 ...
    森殁阅读 147评论 0 0
  • 晚霞将海湾染成金黄 归家的海燕落在海滩上 渔家少女站在海边 两眼忧伤的盯着前方 痴情等着出海的情郎 浪花轻起 一只...
    山上人家123阅读 172评论 4 9
  • 文/熠歆 今天生意的确好很多…… 累得手都爪了一样…… 只想睡觉! 养足精神,明天继续…… 晚安,自己!
    熠歆阅读 135评论 3 2