在Python中,对象是独立的,不一样做用域中的不一样名字均可以被绑定在同一个对象上,固然对这个对象的修改会影响全部的引用。赋值操做就是名字和对象的绑定或重绑定。这和C++中的引用是同样的。html
1,基础概念python
1.1 命名空间(namespace) app
A namespace is a mapping from names to objects函数
命名空间是名字和对象的映射。也就是能够把一个namespace理解为一个字典,实际上不少当前的Python实现namespace就是用的字典。各个命名空间是独立的,没有任何关系的,因此一个命名空间中不能有重名,但不一样的命名空间是能够重名而没有任何影响。测试
那么哪些能够是一个namespace呢,好比Python的built-in names(包括内置函数,内置常量,内置类型);一个模块的global names(这个模块定义的函数,类,变量);一个函数的全部local names;还有一个类对象的全部属性(数据成员,成员函数)都组成一个命名空间。ui
命名空间都是有建立时间和生存期的。对于Python built-in names组成的命名空间,它在Python解释器启动的时候被建立,在解释器退出的时候才被删除;对于一个Python模块的global namespace,它在这个module被import的时候建立,在解释器退出的时候退出;对于一个函数的local namespace,它在函数每次被调用的时候建立,函数返回的时候被删除。spa
[总结]一个模块的引入,函数的调用,类的定义都会引入命名空间,函数中的再定义函数,类中的成员函数定义会在局部namespace中再次引入局部namespace。rest
1.2 做用域(scope) code
A scope is a textual region of a Python program where a namespace is directly accessible.htm
做用域是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