Python 3.x中的nonlocal及其在2.x中的变通办法
by cnDenis http://cndenis.iteye.com 2012年12月26日
在Python 2.x中,函数内部可以定义函数,内层的函数可以读取外层函数的局部变量,但却不可以修改它.
|
#!/usr/bin/python
def outter():
x = 1
def inner():
print("inner is called, x=", x)
return inner
outter()()
|
上面这个程序是没问题的,但是,下面这个就会出错:
|
#!/usr/bin/python
def outter():
x = 1
def inner():
print("inner is called, x=", x)
x = 2
return inner
outter()()
|
提示竟然是UnboundLocalError: local variable 'x' referenced before assignment
,找不到变量。
这个错误在Python 3.x中的解决方法是使用Py3k新增的关键词nonlocal
:
|
#!/usr/bin/python
def outter():
x = 1
def inner():
nonlocal x
print("inner is called, x=", x)
x = 2
return inner
outter()()
|
但Python 2.x中没有这个关键词,怎么办呢?如果对变量的改变的不需要影响外层的话,可以新建一个变量来用也可以。
新建变量的方式:
|
#!/usr/bin/python
def outter():
x = 1
def inner():
y = x
print("inner is called, x=", y)
y = 2
return inner
outter()()
|
由于y是在内层函数中定义的,可以随便改变,但外层函数看不见y。而如果需要内层对变量的改变被外层看到的话,变通的方法是使用可变的对象,例如dict、对像的属性等。例如 Python 3.x中的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/usr/bin/python
def outter():
x = 1
def inner():
nonlocal x
print("inner is called, x=", x)
x = 2
inner()
print("outter after inner called, x=", x)
outter()
#Python 3.3中输出:
#inner is called, x= 1
#outter after inner called, x= 2
|
在Python 2.x中用dict的方式变通为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/usr/bin/python
def outter():
x = {}
x[0] = 1
def inner():
print("inner is called, x=", x[0])
x[0] = 2
inner()
print("outter after inner called, x=", x[0])
outter()
#Python 2.7中输出:
#inner is called, x= 1
#outter after inner called, x= 2
|
用对像的属性的方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#!/usr/bin/python
class C(object):
pass
def outter():
x = C()
x.v = 1
def inner():
print("inner is called, x=", x.v)
x.v = 2
inner()
print("outter after inner called, x=", x.v)
outter()
#Python 2.7中输出:
#inner is called, x= 1
#outter after inner called, x= 2
|
以上内容参考了:Python的闭包与nonlocal 以及 Simulating nonlocal in Python 2.x
分享到:
相关推荐
例如,“中国='china'”这样的代码在Python3.x中是完全合法的,而无需额外的编码声明,这在Python2.x中是不可行的,后者需要明确指定编码。 ### 语法 语法方面的变化相当广泛,包括: - 去除了`<>`比较运算符,...
Python 3.x 和 2.x 是 Python 语言的两个主要版本,它们之间存在诸多差异,这些差异主要体现在性能、编码规范、语法结构以及内置函数等多个方面。以下将详细阐述这些不同点。 首先,从性能角度看,Python 3.x 在...
Python 3.x 和 Python 2.x 是两个主要的 Python 语言版本,它们之间存在诸多差异,这些差异主要体现在性能、编码、语法、数据类型以及内置函数等多个方面。以下是这些关键区别更详细的解释: 1. **性能**: - ...
12. **可迭代解包**:在Python 3.x中,提供了更灵活的解包方式,如`a, b, *rest = seq`或`*rest, a = seq`,只要满足一定的条件即可使用。 通过上述对比,我们可以看出Python3.x在语法设计上更加严谨、一致,并且...
4. **语法改进**:Python 2.7引入了一些3.x系列的新语法特性,比如非本地(nonlocal)关键字,使得在嵌套函数或闭包中修改外部变量变得可能。 5. **异常处理**:Python 2.7 使用`raise`语句可以抛出自定义异常,并...
Python 084.nonlocal_global.mp4
- Python 3.x默认源代码文件使用UTF-8编码,这简化了处理多语言字符的流程,使得像`print(中国)`这样的代码在Python 3.x中是合法的。 3. 语法变化: - 去除了不等运算符`<>`,统一使用`!=`。 - 移除了反引号``,...
两个关键词都用于允许在一个局部作用域中使用外层的变量。 global 表示将变量声明为全局变量 nonlocal 表示将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量) 注意:我使用的是Python3.6.3,可能和...
- **字符串**:**Python 3.x** 中只有一种字符串类型 `str`,其行为类似于 **Python 2.x** 中的 `unicode` 类型。 - **字节串**:引入了 `bytes` 类型来表示字节序列,取代了 **Python 2.x** 中的 `str` 类型作为...
在字符串和字节串处理上,Python3.x统一了字符串类型为`str`,它与Python2.x中的`unicode`类似,而字节序列则由新的`bytes`类型表示。这种变化对处理文本和网络数据流的程序有着深远的影响,确保了更一致的处理方式...
2. **类型系统**:Python 2.7 区分了整数(int)和长整数(long),但在 Python 3.x 中它们被统一为 int 类型。此外,Python 2.7 的除法运算 `/` 对于整数会返回整数结果,而浮点数除法需使用 `//`。 3. **字符串...
2. **非局部(Nonlocal)变量的增强**:在Python 3.7中,非局部变量声明现在可以用于`async def`函数,这使得异步编程中的状态管理更为灵活。 3. **数据类(Data Classes)**:Python 3.7引入了内置的`dataclasses`...
在 Python 2.x 中,2.7 版本是最为广泛使用和受欢迎的,因为它在功能和兼容性上达到了一个很好的平衡。Python 2.7.3 的出现是为了修复之前版本的一些已知问题,并提供了一些新特性,以增强编程体验和提高代码效率。 ...
在Python中,函数是一段可重用的代码块,用于执行特定的任务。定义一个函数使用`def`关键字。例如: ```python def info_1(a, b, c): print(a) print(b) print(c) ``` 这里定义了一个名为`info_1`的函数,接受...
变量在Python编程中扮演着极其重要的角色,它们是用于存储数据值的标识符。理解变量的概念、命名规则以及如何使用它们对于掌握Python编程至关重要。 #### 注释 - **作用**:注释在Python中用于添加解释性文本,帮助...
### Python 2.X 与 3.X 版本的区别详解 Python作为一种广泛使用的高级编程语言,自1991年首次发布以来,经历了多个版本的更迭,其中最显著的两个大版本为Python 2.X 和 Python 3.X。本文将深入探讨这两个版本之间的...
Python 3.3.5是Python 3.x系列的一个版本,它针对64位(amd64)架构进行了优化,适用于Windows操作系统。这个"python-3.3.5.amd64.msi"文件是一个Windows安装程序包,它包含了Python运行环境和开发工具,使得用户...