Python “import“ 语句声明

Python  "import" 语句声明

**********************

   import_stmt     ::= "import" module ["as" identifier] ("," module ["as" identifier])
                   | "from" relative_module "import" identifier ["as" identifier]("," identifier ["as" identifier])
                   | "from" relative_module "import" "(" identifier ["as" identifier]("," identifier ["as" identifier])* [","] ")"
                   | "from" module "import" "*"
   module          ::= (identifier ".")* identifier
   relative_module ::= "."* module | "."+

   import_stmt     ::= "import" module ["as" identifier] ("," module ["as" identifier])
                                | "from" relative_module "import" identifier ["as" identifier]("," identifier ["as" identifier])
                                | "from" relative_module "import" "(" identifier ["as" identifier]("," identifier ["as" identifier])* [","] ")"
                                | "from" module "import" "*"
   module          ::= (identifier ".")* identifier
   relative_module ::= "."* module | "."+

基本的import语句(没有“from”子句)分两步执行:

  1. 找到一个模块,必要时加载并初始化它
  2. 在“import”语句出现的局部命名空间范围内定义一个或多个名称。

当声明语句包含多个子句(用逗号分隔)时,每个子句将分别执行这两个步骤,就像子句被分隔成单独的import语句一样。

第一步的细节,查找和加载模块的描述在导入系统中有更详细的描述,也描述了各种包和模块的变量类型,它们可以被导入,以及所有的钩子,可用于自定义导入系统。
请注意,此步骤中的失败可能表明无法定位模块,*或*在初始化模块(包括执行模块代码)时发生了错误。

如果成功检索到请求的模块,它将以以下三种方式之一在局部命名空间中可用:

  • 如果模块名后面跟着“as”,则“as”后面的名称直接绑定到导入的模块。
  • 如果没有指定其他名称,且被导入的模块是顶级模块,则模块的名称会绑定在本地命名空间中,作为对被导入模块的引用
  • 如果被导入的模块不是顶级模块,那么包含该模块的顶级包的名称会被绑定到本地命名空间中,作为对顶级包的引用。必须使用它的全限定名而不是直接访问被导入的模块。

“from”子句使用了一个稍微复杂一些的过程:

  1. 找到"from"子句中指定的模块,必要时加载并初始化它;
  2. 对于"import"子句中指定的每个标识符:

1.检查导入的模块是否有指定名称的属性;

2.如果没有,尝试以该名称导入子模块,然后再次检查导入的模块是否有该属性;

3.如果未找到该属性,将引发"ImportError"。

4.否则,对该值的引用将存储在局部命名空间中,如果存在,则使用“as”子句中的名称,否则使用属性名称。

示例:

import foo                 # foo imported and bound locally
import foo.bar.baz         # foo.bar.baz imported, foo bound locally
import foo.bar.baz as fbb  # foo.bar.baz imported and bound as fbb
from foo.bar import baz    # foo.bar.baz imported and bound as baz
from foo import attr       # foo imported and foo.attr bound as attr

如果标识符列表被替换为星号("'*'"),那么模块中定义的所有公共名称都被绑定到出现"import"语句的范围的局部命名空间中。

由模块定义的*public names*是通过检查模块命名空间中名为"__all__"的变量来确定的;如果定义了,它必须是一个由该模块定义或导入的名称组成的字符串序列。“__all__”中的名称都被认为是公共的,并且必须存在。如果未定义"__all__",则公共名称集包括模块命名空间中所有不以下划线("'_'")开头的名称。“__all__”应该包含整个公共API。它的目的是避免意外导出不属于API的项(例如在模块中导入和使用的库模块)。

import的通配符形式- "from module import *" -只允许在模块级别。试图在类或函数定义中使用它将引发“SyntaxError”。

当指定要导入的模块时,你不必指定模块的绝对名称。当一个模块或包包含在另一个包中,可以在同一顶部包中进行相对导入,而不必提及包名。通过在指定的模块或包的“from”之后使用前导点,您可以指定在当前包层次结构中向上遍历的高度,而无需指定确切的名称。一个前导点表示进行导入的模块所在的当前包。两个点代表一个包裹等级。三个点就是上升了两个关卡,等等。所以如果你执行from。从"pkg"包中的模块中导入mod,然后你就会导入"pkg.mod"。如果你执行“from ..”从"pkg.subpkg1"中导入"pkg.subpkg2.mod"。相对导入的规范包含在Package relative imports部分。

"importlib.import_module()"用于支持动态确定要加载的模块的应用程序。

 

Future statements
=================

A *future statement* is a directive to the compiler that a particular module should be compiled using syntax or semantics that will be available in a specified future release of Python where the feature becomes standard.

The future statement is intended to ease migration to future versions of Python that introduce incompatible changes to the language.  It allows use of the new features on a per-module basis before the release in which the feature becomes standard.

   future_stmt ::= "from" "__future__" "import" feature ["as" identifier]
                   ("," feature ["as" identifier])*
                   | "from" "__future__" "import" "(" feature ["as" identifier]
                   ("," feature ["as" identifier])* [","] ")"
   feature     ::= identifier

A future statement must appear near the top of the module.  The only lines that can appear before a future statement are:

* the module docstring (if any),

* comments,

* blank lines, and

* other future statements.

The only feature in Python 3.7 that requires using the future statement is "annotations".

All historical features enabled by the future statement are still recognized by Python 3.  The list includes "absolute_import", "division", "generators", "generator_stop", "unicode_literals", "print_function", "nested_scopes" and "with_statement".  They are all redundant because they are always enabled, and only kept for backwards compatibility.

A future statement is recognized and treated specially at compile time: Changes to the semantics of core constructs are often implemented by generating different code.  It may even be the case that a new feature introduces new incompatible syntax (such as a new reserved word), in which case the compiler may need to parse the module differently.  Such decisions cannot be pushed off until runtime.
For any given release, the compiler knows which feature names have been defined, and raises a compile-time error if a future statement contains a feature not known to it.

The direct runtime semantics are the same as for any import statement: there is a standard module "__future__", described later, and it will be imported in the usual way at the time the future statement is executed.

The interesting runtime semantics depend on the specific feature enabled by the future statement.

Note that there is nothing special about the statement:

   import __future__ [as name]

That is not a future statement; it’s an ordinary import statement with no special semantics or syntax restrictions.

Code compiled by calls to the built-in functions "exec()" and "compile()" that occur in a module "M" containing a future statement will, by default, use the new syntax or semantics associated with the future statement.  This can be controlled by optional arguments to "compile()" — see the documentation of that function for details.

A future statement typed at an interactive interpreter prompt will take effect for the rest of the interpreter session.  If an interpreter is started with the "-i" option, is passed a script name to execute, and the script includes a future statement, it will be in effect in the interactive session started after the script is executed.

See also:

  **PEP 236** - Back to the __future__
     The original proposal for the __future__ mechanism.

Related help topics: MODULES

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值