`
cnDenis
  • 浏览: 100357 次
  • 来自: 广州
社区版块
存档分类
最新评论

Python 3.x中的nonlocal及其在2.x中的变通办法

阅读更多

 

Python 3.x中的nonlocal及其在2.x中的变通办法

by cnDenis http://cndenis.iteye.com 2012年12月26日

在Python 2.x中,函数内部可以定义函数,内层的函数可以读取外层函数的局部变量,但却不可以修改它.

1
2
3
4
5
6
7
8
#!/usr/bin/python
def outter():
    x = 1
    def inner():
        print("inner is called, x=", x)
    return inner

outter()()

上面这个程序是没问题的,但是,下面这个就会出错:

1
2
3
4
5
6
7
8
9
#!/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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/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中没有这个关键词,怎么办呢?如果对变量的改变的不需要影响外层的话,可以新建一个变量来用也可以。

新建变量的方式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/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

 

0
4
分享到:
评论

相关推荐

    Python3.x和Python2.x的区别

    例如,“中国='china'”这样的代码在Python3.x中是完全合法的,而无需额外的编码声明,这在Python2.x中是不可行的,后者需要明确指定编码。 ### 语法 语法方面的变化相当广泛,包括: - 去除了`<>`比较运算符,...

    python3.x和2.x的区别(中文)

    Python 3.x 和 2.x 是 Python 语言的两个主要版本,它们之间存在诸多差异,这些差异主要体现在性能、编码规范、语法结构以及内置函数等多个方面。以下将详细阐述这些不同点。 首先,从性能角度看,Python 3.x 在...

    Python3.x和Python2.x的区别.pdf

    Python 3.x 和 Python 2.x 是两个主要的 Python 语言版本,它们之间存在诸多差异,这些差异主要体现在性能、编码、语法、数据类型以及内置函数等多个方面。以下是这些关键区别更详细的解释: 1. **性能**: - ...

    Python3x和Python2x的区别.doc

    12. **可迭代解包**:在Python 3.x中,提供了更灵活的解包方式,如`a, b, *rest = seq`或`*rest, a = seq`,只要满足一定的条件即可使用。 通过上述对比,我们可以看出Python3.x在语法设计上更加严谨、一致,并且...

    python-2.7.15.amd64

    4. **语法改进**:Python 2.7引入了一些3.x系列的新语法特性,比如非本地(nonlocal)关键字,使得在嵌套函数或闭包中修改外部变量变得可能。 5. **异常处理**:Python 2.7 使用`raise`语句可以抛出自定义异常,并...

    Python 084.nonlocal_global.mp4

    Python 084.nonlocal_global.mp4

    Python2.x与Python3.x的区别

    - Python 3.x默认源代码文件使用UTF-8编码,这简化了处理多语言字符的流程,使得像`print(中国)`这样的代码在Python 3.x中是合法的。 3. 语法变化: - 去除了不等运算符`<>`,统一使用`!=`。 - 移除了反引号``,...

    Python中关键字global和nonlocal的区别详解

    两个关键词都用于允许在一个局部作用域中使用外层的变量。 global 表示将变量声明为全局变量 nonlocal 表示将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量) 注意:我使用的是Python3.6.3,可能和...

    Python2与Python3的区别

    - **字符串**:**Python 3.x** 中只有一种字符串类型 `str`,其行为类似于 **Python 2.x** 中的 `unicode` 类型。 - **字节串**:引入了 `bytes` 类型来表示字节序列,取代了 **Python 2.x** 中的 `str` 类型作为...

    Python3_x和Python2_x的区别.pdf

    在字符串和字节串处理上,Python3.x统一了字符串类型为`str`,它与Python2.x中的`unicode`类似,而字节序列则由新的`bytes`类型表示。这种变化对处理文本和网络数据流的程序有着深远的影响,确保了更一致的处理方式...

    python 2.7.14 参考文档

    2. **类型系统**:Python 2.7 区分了整数(int)和长整数(long),但在 Python 3.x 中它们被统一为 int 类型。此外,Python 2.7 的除法运算 `/` 对于整数会返回整数结果,而浮点数除法需使用 `//`。 3. **字符串...

    python3.7.2.zip

    2. **非局部(Nonlocal)变量的增强**:在Python 3.7中,非局部变量声明现在可以用于`async def`函数,这使得异步编程中的状态管理更为灵活。 3. **数据类(Data Classes)**:Python 3.7引入了内置的`dataclasses`...

    python-2.7.3

    在 Python 2.x 中,2.7 版本是最为广泛使用和受欢迎的,因为它在功能和兼容性上达到了一个很好的平衡。Python 2.7.3 的出现是为了修复之前版本的一些已知问题,并提供了一些新特性,以增强编程体验和提高代码效率。 ...

    Python函数.md

    在Python中,函数是一段可重用的代码块,用于执行特定的任务。定义一个函数使用`def`关键字。例如: ```python def info_1(a, b, c): print(a) print(b) print(c) ``` 这里定义了一个名为`info_1`的函数,接受...

    python变量.pdf

    变量在Python编程中扮演着极其重要的角色,它们是用于存储数据值的标识符。理解变量的概念、命名规则以及如何使用它们对于掌握Python编程至关重要。 #### 注释 - **作用**:注释在Python中用于添加解释性文本,帮助...

    python版本区别

    ### Python 2.X 与 3.X 版本的区别详解 Python作为一种广泛使用的高级编程语言,自1991年首次发布以来,经历了多个版本的更迭,其中最显著的两个大版本为Python 2.X 和 Python 3.X。本文将深入探讨这两个版本之间的...

    python官方3.3.5.amd64版本msi安装包

    Python 3.3.5是Python 3.x系列的一个版本,它针对64位(amd64)架构进行了优化,适用于Windows操作系统。这个"python-3.3.5.amd64.msi"文件是一个Windows安装程序包,它包含了Python运行环境和开发工具,使得用户...

Global site tag (gtag.js) - Google Analytics