Python基础-作用域和命名空间(Scope and Namespace)

在Python中,对象是独立的,不同作用域中的不同名字都可以被绑定在同一个对象上,当然对这个对象的修改会影响所有的引用。赋值操作就是名字和对象的绑定或重绑定。这和C++中的引用是一样的。

1,基础概念

1.1 命名空间(namespace)

namespace is a mapping from names to objects

命名空间是名字和对象的映射。也就是可以把一个namespace理解为一个字典,实际上很多当前的Python实现namespace就是用的字典。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。

那么哪些可以是一个namespace呢,比如Python的built-in names(包括内置函数,内置常量,内置类型);一个模块的global names(这个模块定义的函数,类,变量);一个函数的所有local names;还有一个类对象的所有属性(数据成员,成员函数)都组成一个命名空间。

命名空间都是有创建时间和生存期的。对于Python built-in names组成的命名空间,它在Python解释器启动的时候被创建,在解释器退出的时候才被删除;对于一个Python模块的global namespace,它在这个module被import的时候创建,在解释器退出的时候退出;对于一个函数的local namespace,它在函数每次被调用的时候创建,函数返回的时候被删除。

[总结]一个模块的引入,函数的调用,类的定义都会引入命名空间,函数中的再定义函数,类中的成员函数定义会在局部namespace中再次引入局部namespace。

1.2 作用域(scope)

scope is a textual region of a Python program where a namespace is directly accessible.

作用域是Python程序(文本)的某一段或某些段,在这些地方,某个命名空间中的名字可以被直接引用。这个作用域就是这个命名空间的作用域。

一个Python程序的几个作用域:

--最里面的局部作用域

--外层函数的局部作用域

--模块的全局作用域

--包含Python内置对象的最外层作用域

关于作用域,参加Python基础-函数这片博客中2小节的例子。

1.3 赋值(assignment)

Assignments do not copy data — they just bind names to objects.

赋值操作不会拷贝,只是把名字和对象做一个绑定。也就是赋值语句是起一个绑定或重绑定的作用(bind or rebind)。函数调用的参数传递是赋值,不是拷贝。

2,global和nonlocal语句

global语句用来声明一系列变量,这些变量会引用到当前模块的全局命名空间的变量(module-level namespace),如果该变量没有定义,也会在全局空间中添加这个变量。

global var1, var2

nonlocal语句(nonlocal是Python3.2引入的)

Python2.7中还没有nonlocal语句。nonlocal语句用来声明一系列的变量,这个声明会从声明处从里到外的namespace去搜寻这个变量(the nearest enclosing scope),直到模块的全局域(不包括全局域),找到了则引用这个命名空间的这个名字和对象,若作赋值操作,则直接改变外层域中的这个名字的绑定。nonlocal语句声明的变量不会在当前scope的namespace字典中加入一个key-value对,如果在外层域中没有找到,则如下报错。

>>>SyntaxError: no binding for nonlocal 'spam' found

一个nonlocal和global的测试例子

 1 def test():
2 def do_local():
3 spam = "local spam"
4 def do_nonlocal():
5 nonlocal spam
6 spam = "nonlocal spam"
7 def do_global():
8 global spam
9 spam = "global spam"
10 spam = "test spam"
11 do_local()
12 print("after local assignment:", spam) #输出:test spam
13 do_nonlocal()
14 print("after nonlocal asssignment:", spam) #输出:nonlocal spam
15 do_global()
16 print("after global assignment:", spam) #输出:nonlocal spam
17
18 test()
19 print("in global scope:", spam) #输出:global spam

第5行的语句:nonlocal spam 没有在函数do_nonlocal()的域中创建一个变量,而是去引用到了外层的,10行定义的spam。

第8行的global spam,在全局域中创建了一个name,9行将其绑定在字符串常量对象"global spam"上。

跟进一步测试nonlocal

 1 def test():
2 def do_nonlocal():
3 nonlocal spam
4 def do_nonlocal2():
5 nonlocal spam
6 spam = "nonlocal2 spam" #修改了test()中spam的绑定
7 do_nonlocal2()
8 spam = "test spam"
9 do_nonlocal()
10 print("after nonlocal2 asssignment:", spam) #输出:nonlocal2 spam
11 test()

do_nonlocal2()中的spam引用的是其外面的二层,也就是test()函数域中的spam。

参考:

http://docs.python.org/3.3/tutorial/classes.html#python-scopes-and-namespaces   Python文档

http://docs.python.org/3.2/reference/simple_stmts.html  Python文档-simple statement

 
 
分类: Python

Scope and Namespace的更多相关文章

  1. Python基础-作用域和命名空间(Scope and Namespace)

    在Python中,对象是独立的,不同作用域中的不同名字都可以被绑定在同一个对象上,当然对这个对象的修改会影响所有的引用.赋值操作就是名字和对象的绑定或重绑定.这和C++中的引用是一样的. 1,基础概念 ...

  2. C++ 名字空间namespace的使用

    A namespace is a scope.C++ provides namespaces to prevent name conflicts.A namespace is a mechanism ...

  3. C++——namespace

    scope和namespace scope就是我们常说的作用域,namespace是C++引入的一个关键字.这两种都和作用域有些微妙的联系,下面 引自Global scope vs global na ...

  4. SSH整合之全注解

    SSH整合之全注解 使用注解配置,需要我们额外引入以下jar包

  5. Laravel5.1-Eloquent ORM:起步

    概述 有很多朋友问,MCV的M是在哪里介绍的,这里就是介绍M的地方了.Laravel有一个强大的数据库ORM Eloquent,它的原理是每张数据表对应一个Model,对Model的操作就对应数据库的 ...

  6. [Python] Symbol Review

    From:http://learnpythonthehardway.org/book/ex37.html 1. with X as Y: pass 1.1 yield 2. exec 2.1 name ...

  7. S2SH项目框架搭建(完全注解)

    1.引入相关jar包 2.配置Spring配置文件,命名为applicationContext.xml(配置好后放到src目录下) <beans xmlns="http://www.s ...

  8. 使用jQuery验证用户名是否存在,达到局部刷新的效果

    <%@ page pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...

  9. Unqualified name lookup

    Unqualified name lookup File scope Namespace scope For an qualified name, that is a name that does n ...

随机推荐

  1. HDU 4107 线段树

    给出N个节点,M次操作,和p 每次操作 对l-r区间的每一个节点+c,若节点值>=p,则加2*c: 结点存当前区间伤害最小值,最大值,以及lazy操作.更新到假设最小值大于等于P,或者最大值小于 ...

  2. Scrapy研究和探索(七)——如何防止被ban大集合策略

    说来设置的尝试download_delay少于1,不管对方是什么,以防止ban策略后.我终于成功ban该. 大约scrapy利用能看到以前的文章: http://blog.csdn.net/u0121 ...

  3. JavaWeb显示器

    本文研究的总结.欢迎转载,但请注明出处:http://blog.csdn.net/pistolove/article/details/44310967 A:监听器的定义      专门用于其它对象身上 ...

  4. typecheck()简析

    #define typecheck(type,x) \ ({ type __dummy; \ typeof(x) __dummy2; \ (void)(&__dummy == &__d ...

  5. AngularJS应用开发思维之2:数据绑定

    在声明式模板中显示数据 因为不能像jQuery一样将DOM操作混在模板里,声明式模板很快让我们变得束手束脚. 一个典型的问题:在声明式模板里怎么显示数据? 假设我们有某人的基本信息,保存在一个json ...

  6. 【hoj】2651 pie 二分查找

    二分查找是一个非常主要的算法,针对的是有序的数列,通过中间值的大小来推断接下来查找的是左半段还是右半段,直到中间值的大小等于要找到的数时或者中间值满足一定的条件就返回,所以当有些问题要求在一定范围内找 ...

  7. Android单元测试Junit (一)

    1.在eclips中建立一个Android工程,具体信息如下: 2.配置单元测试环境,打开AndroidManifest.xml,具体代码如下所示: <?xml version="1. ...

  8. 什么是Solr搜索

    什么是Solr搜索 一.Solr综述   什么是Solr搜索 我们经常会用到搜索功能,所以也比较熟悉,这里就简单的介绍一下搜索的原理. 当然只是介绍solr的原理,并不是搜索引擎的原理,那会更复杂. ...

  9. Git工作流:中心工作流(翻译)

    使用Git作为版本控制器,有众多可能的工作流(Workflow),这使得我们这些新鸟不知道在实际工作中不知道该选择哪种工作流.这里我们对最常见的Git工作流做一个对比,为企业团队提供一个参考. 正如你 ...

  10. 使用Json实体类构建菜单数据

    基于MVC4+EasyUI的Web开发框架经验总结(3)- 使用Json实体类构建菜单数据 最近花了不少时间在重构和进一步提炼我的Web开发框架上,力求在用户体验和界面设计方面,和Winform开发框 ...