关于闭包的基础理解

        闭包(closure)定义是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)。定义里这个引用环境并不易懂。实际来说,pyhton 中函数是可以嵌套的,如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。

>>>def addx(x):  
>>>    def adder(y): return x + y  
>>>    return adder  
>>> c =  addx(8)  
>>> type(c)  
<type 'function'>  
>>> c.__name__  
'adder'  
>>> c(10)

返回函数名而并不立即执行,这里内部函数adder 调用了外部作用域的x。

但是内部函数并不能修改外部作用域的变量:

def foo():  
    a = 1  
    def bar():  
        a = a + 1  
        return a  
    return bar

这一段代码会报错,显示bar函数内的a未被定义。

可以再定义同名的变量,但是内部是内部变量,外部是外部变量,并不互相影响。

def foo():
    m = 0
    def foo1():
        m = 1
        print(m)
    print(m)
    foo1()
    print(m)
foo()

结果是 0 1 0

解决方案,python3通过nonlocal关键字来解决:

def foo():
    m = 0
    def foo1():
        nonlocal m
        m = 1
        print(m)
    print(m)
    foo1()
    print(m)
foo()

该语句指定m并不是函数内局部变量。

 

下面是看到别人使用闭包的例子,还不是甚懂,先粘上来。比如说,如果你希望函数的每次执行结果,都是基于这个函数上次的运行结果。我以一个类似棋盘游戏的例子来说明。假设棋盘大小为50*50,左上角为坐标系原点(0,0),我需要一个函数,接收2个参数,分别为方向(direction),步长(step),该函数控制棋子的运动。棋子运动的新的坐标除了依赖于方向和步长以外,当然还要根据原来所处的坐标点,用闭包就可以保持住这个棋子原来所处的坐标。

origin = [0, 0] 
legal_x = [0, 50]  
legal_y = [0, 50] 
def create(pos=origin):   
    def player(direction,step):    
        # 这里应该首先判断参数direction,step的合法性,比如direction不能斜着走,step不能为负等    
        # 然后还要对新生成的x,y坐标的合法性进行判断处理,这里主要是想介绍闭包,就不详细写了。    
        new_x = pos[0] + direction[0]*step    
        new_y = pos[1] + direction[1]*step    
        pos[0] = new_x    
        pos[1] = new_y    
        #注意!此处不能写成 pos = [new_x, new_y],因为参数变量不能被修改,而pos[]是容器类的解决方法 
        return pos   
    return player    

player = create() # 创建棋子player,起点为原点  
print player([1,0],10) # 向x轴正方向移动10步  
print player([0,1],20) # 向y轴正方向移动20步  
print player([-1,0],10) # 向x轴负方向移动10步

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值