Notes on Python Naming and binding

本文深入探讨了Python中的全局(global)和非局部(nonlocal)变量声明的概念,并通过具体示例展示了如何在不同作用域中访问和修改变量。同时,对比了Python 2与Python 3在作用域处理上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在看Python Language Reference的第四章Execution model的第一节4.1 Naming and binding时,看了好几遍才明白,特意整理一下,以供参考。

 

首先明确两个概念:global和nonlocal(Python 3才引入,我用的版本是3.2a3)

The global statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals. It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global.

简单地说,global关键字使得一个variable拥有module scope,所以有时候也叫module-global scope。

 

执行结果:

Inside the function var is bar

Outside the function var is bar

但是global解决不了“access to names in outer scopes",比如下面的例子:

 

执行结果为:

 

inside inner, var6 is bar

Inside outer function, var6 is foo

 

 

 

 

 

这也正是Python3引入nonlocal的原因,nonlocal关键字赋予了访问外一层scope里name的能力,比如把上面例子中的global替换成nonlocal,结果就变成了:

 

inside inner, var6 is bar

Inside outer function, var6 is bar

 

 


The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope. This is important because the default behavior for binding is to search the local namesapce first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.

 

Names listed in a nonlocal statement, unlike to those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).

对于nonlocal引入的背景,可以看PEP 3104(类似于Java里的JSR):http://www.python.org/dev/peps/pep-3104/

 

如果你还在用Python2,你可以使用一些变通的方法达到nonlocal的效果:http://www.saltycrane.com/blog/2008/01/python-variable-scope-notes/

 

下面是一个综合使用nonlocal和global的例子:

 

结果是:

After local assignment: test spam

After nonlocal assignment: nonlocal spam

After global assignment: nonlocal spam

In global scope: global spam

 

讲到scope的时候,特别要注意的是在class block里面定义的name的scope,它不包含类里面的方法——包括comprehensions和generator expression,除了文档里面的例子外,我们可以看下面的例子:

 

 

运行时会报错:NameError: global name 'var7' is not defined,说明访问var7出错了,这跟Java很不一样,在上面的例子中,如果我们希望访问var7,必须加上self.前缀。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值