Python 3.7» Documentation » The Python Tutorial »

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.

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(在计算模式下)).

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:

# 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:

>>>

>>> 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.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 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:

>>>

>>> 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:

>>>

>>> 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.

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. (typing输入)

If the module name is followed by as, then the name following as is bound directly to the imported module.

>>>

>>> 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.

It can also be used when utilising() from with similar effects:

>>>

>>> 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(),例如,进口导入库;importlib.reload(模块名)。

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

When you run a Python module with

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:

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.pathsys.path is initialized(初始化) from these locations:

模块搜索途径:1built_in模块  2、在sys.path字典中所有spam.py的关键字

  • 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).目录名列表,语法与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.在标准库路径之前。 这意味着将加载该目录中的脚本,而不是库目录中的同名模块。 除非有意更换,否则这是一个错误。 有关更多信息,请参见标准模块一节

6.1.3. “Compiled” Python files

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(优化).
  • 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.

6.2. Standard Modules

Python comes with(附带) a library of standard modules(标准库模块), described in a separate document(在另一份文件中描述), the Python Library Reference(python参考库) (“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解释器中。 变量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获取的默认路径,或者如果未设置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:

内置函数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:

>>>

>>> 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:

>>>

>>> 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 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 Pillow from having to worry about each other’s module names.

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):

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(子目录).

The __init__.py files are required to make Python treat the directories as containing packages(需要__init__.py文件才能使Python将目录视为包含包); this is done to prevent directories with a common name, such as string(这样做是为了防止具有通用名称的目录,例如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.

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.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.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:

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.

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.

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.(准确引用)

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 sound/effects/__init__.py could contain the following code:

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

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

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:

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.)

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.

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.

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.vocoderneeds to use the echo module in the sound.effects package, it can use 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 surroundmodule for example, you might use:

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__。 这被初始化为一个列表,其中包含在执行该文件中的代码之前保存包的__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.[1]事实上,函数定义也是“执行”的“语句”; 模块级函数定义的执行在模块的全局符号表中输入函数名。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值