<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>”,它的作用方式与global类似,但对于嵌套的函数作用域。</p>