4.1. 命名与绑定¶
变量名 指定对象.变量通过名称绑定完成.每一个变量通过绑定 之后供程序调用.
一个块是一段单独python代码.块包括: 一个模块,一段方法体,一个类.每个可交互的命令的是一个块.一个脚本文件 (可以被解释器当做标准输出或命令行参数)是一段代码块.一个脚本命令(一个指定了 ‘-c‘ 选项的命令行)是一段代码块.需要传入字符参数的内建方法 eval() 和 exec() 也是代码块.
一个代码块就是一个 执行片段.一个片段包含一些信息 (用于调试) 且决定在何时并以何种方式继续执行下一段代码.
scope 定义了在一个块内变量的可见性.如果在一个块内定义的变量,他的scope就是这个块.如果定义在一个方法块中, scope为所有调用此方法的块,除了那些给这个变量重新绑定成其它对象的块之外.变量在一个类块中的scope为当前的类;但这并非说明可以在类中任意使用.也就是说下面这段代码执行会失败:
class A:
a = 42
b = list(a + i for i in range(10))
当一个代码块中使用一个变量名时 它只能用于最近的scope.这些对于代码块的可见范围被称做代码块的 环境.
如果一个变量名被绑定到一个块内,那么它对于这个块来说就是一个局部变量除非将其声明为nonlocal.如果一个变量名被绑定在一个模块的范围内,那么它是一个全局变量.(定义在模块中的变量既是本地变量也是全局变量.)如果一个变量在代码块中只使用但未定义,那么他是一个 自由变量.
在“变量名“根本找不到时,就会抛出 NameError 异常.如果变量名引用了一个未绑定的局部变量,就会抛出 UnboundLocalError 异常。
The following constructs bind names: formal parameters to functions, import statements, class and function definitions (these bind the class or function name in the defining block), and targets that are identifiers if occurring in an assignment, for loop header, or after as in a with statement or except clause.The import statement of the form from ...import*binds all names defined in the imported module, except those beginning with an underscore.这种形式只可以在模块级别使用。
A target occurring in a del statement is also considered bound for this purpose (though the actual semantics are to unbind the name).
每个赋值和导入语句出现在类或函数定义的代码块中或者出现在模块级别(顶级代码块)。
如果在代码块的任意地方出现名称绑定操作,那么代码块中该名称的所有使用将被当做对当前代码块的引用。当名称在一个代码块中绑定之前使用时将导致错误。这个规则是微妙的。Python缺少声明并允许名称绑定操作出现在代码块内任何地方。代码块的局部变量通过扫描代码块的全部文本的名称绑定操作决定。
If the global statement occurs within a block, all uses of the name specified in the statement refer to the binding of that name in the top-level namespace.Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, and the builtins namespace, the namespace of the module builtins.首先查找全局命名空间。如果那里找不到名称,就会查找内建的命名空间。The global statement must precede all uses of the name.
与执行的代码块相关联的内建命名空间实际上是通过查找它的全局命名空间中的__builtins__名称找到的;this should be a dictionary or a module (in the latter case the module’s dictionary is used).By default, when in the __main__ module, __builtins__ is the built-in module builtins;when in any other module, __builtins__ is an alias for the dictionary of the builtins module itself.__builtins__可以被设置成一个用户创建的字典以创建一个严格执行的弱形式。
CPython实现细节:Users should not touch __builtins__;it is strictly an implementation detail.Users wanting to override values in the builtins namespace should import the builtins module and modify its attributes appropriately.
模块的命名空间在模块第一次导入时自动创建。脚本的主模块总是被称为
global语句具有和同一个代码块中名称绑定操作相同的定义域。如果包含自由变量的最内层定义域包含一条global语句,那么这个自由变量被认为是一个全局变量。
类定义是一条可以使用和定义名称的可执行语句。这些引用遵循名称解析的正常规则。类定义的命名空间变成类的属性字典。类定义域中定义的名称在方法中不可见。
4.1.1. 与动态功能的交互¶
当与包含自由变量的嵌套定义域联合使用的时候,有几种Python语句是非法的情况。
如果变量在一个包含它的定义域中被引用,那么删除它的名称是非法的。在编译的时刻将会报告一个错误。
The eval() and exec() functions do not have access to the full environment for resolving names.名称可以在调用者的局部和全局命名空间中解析。自由变量不是在包含它们的最内层命名空间中解析,而是在全局命名空间中。[1] The exec() and eval() functions have optional arguments to override the global and local namespace.如果只指明一个命名空间,则两个命名空间都会使用它。