对象具有个性,多个名称(在多个作用域内)可以绑定到同一个对象。
namespace (命名空间)是一个从名字到对象的映射。
任何跟在一个点号之后的名称都称为 属性 — 例如,在表达式 z.real 中,real 是对象 z 的一个属性。按严格的说法, 对模块中名称的引用属于属性引用:在表达式 modname.funcname 中,modname 是一个模块对象而 funcname 是它的一个 属性。在此情况下在模块的属性和模块中定义的全局名称之间正好存在一个直观的映射:它们共享相同的命名空间!
属性可以是只读或者可写的。如果为后者,那么对属性的赋值是可行的。模块属性是可以写,你可以写出 modname.the_answer = 42 。 可写的属性同样可以用 del 语句删除。例如, del modname.the_answer 将会从名为 modname 的对象中移除 the_answer 属性。
一个 作用域 是一个命名空间可直接访问的 Python 程序的文本区域。 这里的 “可直接访问” 意味着对名称的非限定引用会尝试在 命名空间中查找名称。
作用域被静态确定,但被动态使用。 在程序运行的任何时间,至少有三个命名空间可被直接访问的嵌套作用域:
最先搜索的最内部作用域包含局部名称
从最近的封闭作用域开始搜索的任何封闭函数的作用域包含非局部名称,也包括非全局名称
倒数第二个作用域包含当前模块的全局名称
最外面的作用域(最后搜索)是包含内置名称的命名空间
Python 的一个特殊规定是这样的 – 如果不存在生效的 global 或 nonlocal 语句 – 则对名称的赋值总是会进入最内层作用域。 赋值不会复制数据 — 它们只是将名称绑定到对象。 删除也是如此:语句 del x 会从局部作用域所引用的命名空间中移除对 x 的绑定。 事实上,所有引入新名称的操作都是使用局部作用域:特别地,import 语句和函数定义会在局部作用域中绑定模块或函数名称。
global 语句可被用来表明特定变量生存于全局作用域并且应当在其中被重新绑定;nonlocal 语句表明特定变量生存于外层作用域中并且应当在其中被重新绑定。