<p>从本质上讲,Python中唯一引入新作用域的是函数定义。类是一种特殊情况,因为直接在主体中定义的任何内容都放在类的命名空间中,但它们不能从它们包含的方法(或嵌套类)中直接访问</p>
<p>在您的示例中,只有3个作用域将在其中搜索x:</p>
<ul>
<li><p>垃圾邮件的范围-包含code3和code5中定义的所有内容(以及code4,循环变量)</p></li>
<li><p>全局范围-包含code1中定义的所有内容,以及Foo(以及此后的任何更改)</p></li>
<li><p>内置名称空间。有一点特殊——它包含各种Python内置函数和类型,如len()和str()。一般来说,这不应该被任何用户代码修改,所以希望它包含标准函数而不包含其他内容</p></li>
</ul>
<p>只有在图片中引入嵌套函数(或lambda)时,才会出现更多作用域。
然而,它们的行为将与您预期的非常相似。嵌套函数可以访问本地范围内的所有内容,以及封闭函数范围内的任何内容。例如</p>
<pre><code>def foo():
x=4
def bar():
print x # Accesses x from foo's scope
bar() # Prints 4
x=5
bar() # Prints 5
</code></pre>
<p><strong>限制:</strong></p>
<p>可以访问除局部函数变量以外的作用域中的变量,但如果没有进一步的语法,则无法恢复到新参数。相反,赋值将创建一个新的<strong>局部<strong>变量,而不会影响父范围中的变量。例如:</p>
<pre><code>global_var1 = []
global_var2 = 1
def func():
# This is OK: It's just accessing, not rebinding
global_var1.append(4)
# This won't affect global_var2. Instead it creates a new variable
global_var2 = 2
local1 = 4
def embedded_func():
# Again, this doen't affect func's local1 variable. It creates a
# new local variable also called local1 instead.
local1 = 5
print local1
embedded_func() # Prints 5
print local1 # Prints 4
</code></pre>
<p>为了从函数范围内实际修改全局变量的绑定,需要使用global关键字指定该变量为全局变量。例如:</p>
<pre><code>global_var = 4
def change_global():
global global_var
global_var = global_var + 1
</code></pre>
<p>目前没有办法对封闭<em>函数</em>作用域的变量执行相同的操作,但是Python 3引入了一个新的关键字“<code>nonlocal</code>”,它将以类似于全局的方式运行,但用于嵌套函数作用域</p>