所谓名字的scope,指当绑定了一个名字到一个对象的时候,该名字在程序文本中的可见范围。
这是一个基础问题,很重要。非常详细的见官方文档:https://docs.python.org/2/reference/executionmodel.html,但文档中部分内容不容易理解,所以需要我这篇文字来记录我的理解。
对了,这里讨论的是python2.7,但python3是基本一样的。
我在记忆和理解这个问题的时候,是从反过来的思路思考的,既当程序文本中出现了一个名字,如何判断这个名字所绑定的对象。
LEGB原则:
1,local 首先该名字所在的函数block中寻找是否有对该名字的赋值,如果有,那么这就是绑定操作发生的地方。找到则done!
2,enclosing Function local 然后找任意的enclosing functions是否有对该名字的赋值。所谓enclosing function就是涉及到nested function的概念反过来理解。找到则done!
3,global 然后在global scope中找,即在一个module的top level中,或者是在一个函数中但是有声明global的名字的赋值操作。
4,如果还没找到就看有没有build in的名字了。
如果全都没找到,程序执行会产生异常。
这里有另一种情况,如果一个名字出现在class block的top level中,则先在该class的top level中、且在该名字在程序文本中的前面去找,如果有对该名字的赋值,那就是绑定操作发生的地方。否则就跳到global scope中去找。
另外一个要注意对地方,假如一个名字出现在function中,且改function中有对该名字做赋值操作,但是是在该名字的后面,即先引用再赋值,那么该名字的绑定操作就是在此处,而不会再去enclosing、global以及build in的scope中找了,但是,程序执行回异常,会说引用发生在赋值之前。
注,我参考了
http://stackoverflow.com/questions/291978/short-description-of-python-scoping-rules 中的rizwan和antti两位答案。