Python3.2官方文档翻译--作用域和命名空间

6.2 Python作用域和命名空间

在介绍类之前,首先我想告诉你一些关于python作用域的规则。类的定义非常巧妙地运用了命名空间,你需要知道范围和命名空间的工作原理以能全面了解接下来发生的。 顺便说一下,关于这节讲到的知识对于任何优秀的python程序员非常有用。

让我们开始以一些定义开始。

命名空间(namespace)是一个从名称到对象的映射。大多命名空间目前用Python字典实现的,但那通常不会被注意(除非为了性能),在将来它可以改变。命名空间的例子是:内置名称的set(包含函数如abs()和内置异常名称);在模块中的全局变量名称;在函数调用时的局部名称。在一定程度上对象的属性赋值形成一个命名空间。掌握命名空间的重要事情是在不同的命名空间绝对没有关系。例如,两个不同的模块都可以不混淆的定义方法maximize。模块的用户必须用模块名称为前缀。

随便说一下,我习惯上吧每一个跟在点号(.)后面的属性都称为属性(attribute)。例如在表达式z.real。Real是对象z的一个属性。严格意义上讲,在模块中引用的名称都是属性的引用:在表达式modname.funcname,modname是一个模块对象和funcnam是它的一个属性。 在这个例子,这恰好是在于模块属性和在模块定义中的全局变量名称之间的一个简单的映射:它们共享同样的命名空间。

属性是可读的或者是可写的。在后一种情况下,允许对属性赋值。如果模块属性是可写的,你可以这么写,modername.the_answer = 42. 可写属性也可以用del语句删除。例如,del modname.the_answer将会从名叫modname模块中移除属性 the_answer。

命名空间可以在不同的时间里存在并且有不同的生命周期。当python解释器启动时,包含内置名称的命名空间就会创建。并且从不删除。当模块定义读入时,模块的全局命名空间就会创建。正常来说,模块命名空间一直存在直到解释器退出。通过解释器的顶层调用执行,从脚本文件中读取或者交互,都认为是_main_模块的一部分,因此他们也有自己的全局命名空间。(内置名称实际也存在于一个模块,称为builtins.)

当函数调用时函数的局部命名空间就会创建,当函数返回值或者抛出在方法中没有处理的异常时,就会删除。当然,每个递归调用都有自己的局部命名空间。

作用域就是一个python程序可以直接访问命名空间的正文区域。这里“直接访问”的意思就是一个名称的非法引用试图在命名空间中寻找名称。

尽管作用域都是静态定义,但是它们动态使用。在执行过程中的任何时候,至少有给三个关联的命名空间可以直接访问的作用域:

l 首先被查的是包含局部变量的最内层作用域

l 任何关闭函数的作用域,它们以最近封装的作用域开始进行查询,包含的不是局部变量也不是非全局变量。

l 接着查询包含当前模块全局变量的作用域。

l 最后查询的就是最外面的作用域,它是包含内置方法的命名空间。

如果名称定义为全局的,那么所有的引用和赋值都可以直接给包含模块全局变量的中间作用域。为了重新绑定在最内层作用域外面发现的变量,nonlocal语句可以使用。如果没有定义为非本地,这边变量只能读取。(读取这种变量的尝试就会在最内层作用域中产生一个本地局部变量,而外部那个相同标识符的变量不会改变)

通常,局部作用域引用当前函数的局部变量。函数外面,局部作用域引用引用和全局作用一样的命名空间:模块命名空间。类定义也会在局部作用域中引入另一个命名空间。

知道作用域可以在文本中定义是非常重要的。在模块中定义函数的全局作用域是那个模块的命名空间,不管函数从哪里或者用何种名称调用。另一方面,对名称的真正查询是在运行时候动态查询的。但是,语言的定义正在向编译时静态名称确定进化,因此不要依赖动态名称解决。(事实上,局部变量已经静态定义了)

Python一个特别之处是--如果没有全局变量有效--名称的赋值常常进入最内层的范围。赋值不会拷贝数据--它们紧紧是把名称绑定在对象上。删除也是一样。Del语句就会移除从局部作用域的命名空间去掉与x的绑定。事实上,介绍新名称的所有操作都用局部变量,特别是,import语句和函数定义在局部局部作用域中绑定模块或者函数名称。

Global语句可以用来描述活动在全局作用域中的特别变量并且应该绑定在那里。Nonlocal语句描述活动在封装作用域中的特别变量并在那里绑定。

时间: 2024-10-26 23:41:52

Python3.2官方文档翻译--作用域和命名空间的相关文章

Python3.2官方文档翻译--作用域和命名空间实例

6.2.1 作用域和命名空间实例 以下的实例主要用来示范怎样引用不同的作用域和命名空间,keywordglobal和nonlocalru怎样影响变量绑定. 实例执行结果是: After local assignment: test spam After nonlocal assignment: nonlocal spam After global assignment: nonlocal spam In global scope: global spam 注意局部赋值(这是默认的)不能改变sco

Python3.2官方文档翻译---类一些说明

6.4 一些说明 数据属性可以重写同名的方法属性.这是为了避免在大型系统中产生问题的意外名称冲突.所以用一些减少冲突的常用方法是很有效果的.常用的方法包括:大写字母方法名称,用唯一的字符串来做为数据属性的名称(可以是个下划线_)或者用动词命名方法和用名字命名数据属性. 数据属性就像和对象的普通用户一样可以被方法引用.换句话说,类不能用来实现纯净的数据类型.事实上,在python中不能强制数据隐藏,一切基于约定.(另一方面,如C中写的,python的实现可以做到完全隐藏实现细节并且在必要是可以控制

Python3.2官方文档翻译--继承

6.5 继承 当然,一门语言特性如果不支持继承那么名称类就失去了价值.子类继承父类的方法如下: class DerivedClassName(BaseClassName): <statement-1> . . . <statement-N> 名称BaseClassName必须定义在一个包含派生类定义的作用域中.在基类名称的位置上,其他随意表达式都是允许的.例如,当基类定义在其他模块中,这也是可用的. class DerivedClassName(modname.BaseClassN

Python3.2官方文档翻译--标准库概览(一)

7.1 操作系统接口 Os模块提供主要许多与操作系统交互的函数. >>> import os >>> os.getcwd() # Return the current working directory 'C:\\Python31' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # R

Python3.2官方文档翻译-标准库概览(二)

7.5 字符串模式匹配 re模块为高级字符串成处理提供了正则表达式匹配. 对于复杂的匹配和处理,正则表达式能够提供简明优化的方法: >>> import re >>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') ['foot', 'fell', 'fastest'] >>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat'

Python3.2官方文档翻译--输出格式化

第八章 标准库二 第二部分涵盖了许多更能满足专业开发人员需求的高级模块.这些模块在小脚本中很少出现. 8.1 输出格式化 Reprlib模块为大型的或深度嵌套的容器缩写显示提供了repr()函数的一个定制版本. >>> import reprlib >>> reprlib.repr(set('supercalifragilisticexpialidocious')) "set(['a', 'c', 'd', 'e', 'f', 'g', ...])"

Python3.2官方文档翻译--模板

8.2 模板 String模块包含一个用途广泛的类,此类为最终用户的编辑提供了简单的语法支持.这让用户不修改应用程序的前提下实现他们应用程序的定制. 这种格式使用$加有效的python标识符(数字.字母和下划线)形式的占位符名称.通过在占位符两侧使用大括号便可以不用空格分隔在其后面跟随更多的字母和数字字符.使用$$来创建一个单独$转码字符. >>> from string import Template >>> t = Template('${village}folk 

Python3.2官方文档翻译--使用二进制数据记录布局和多线程

题目描述 有n张卡片,分别标有数字1~n.有一天Silence把他们按某种序列排好,然后从第一张开始取出一张,再拿一张放到最后面,再取出一张,再拿出一张放到最后面...知道n张卡片全部取走.把取出的卡片按取出的顺序排好,正好是1,2,3,4,....,n. 现在,告诉你n,Silence希望你帮他计算原来的序列的逆序数. 例如,n=4时,原来的序列应该是1,3,2,4.这样,先取出卡片1,再把卡片3放到最后面,序列变成了2,4,3.再把2取出来,4放到后面,序列变成了3,4.再把3取出来,4放最

Python3.2官方文档翻译-列表工具和十进制浮点数计算

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2368    Accepted Submission(s): 333 Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景.磁