一般来说闭包这个概念在很多语言中都有涉及,本文主要谈谈python中的闭包定义及相关用法。Python中使用闭包主要是在进行函数式开发时使用。详情分析如下:
一、定义
python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).这个定义是相对直白的,好理解的,不像其他定义那样学究味道十足(那些学究味道重的解释,在对一个名词的解释过程中又充满了一堆让人抓狂的其他陌生名词,不适合初学者)。下面举一个简单的例子来说明。
>>>def addx(x): >>> def adder(y): return x + y >>> return adder >>> c = addx(8) >>> type(c) <type 'function'> >>> c.__name__ 'adder' >>> c(10) 18
结合这段简单的代码和定义来说明闭包:
如果在一个内部函数里:adder(y)就是这个内部函数,
对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域addx里面,但不在全局作用域里,
则这个内部函数adder就是一个闭包。
再稍微讲究一点的解释是,闭包=函数块+定义函数时的环境,adder就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x。
二、使用闭包注意事项
1.闭包中是不能修改外部作用域的局部变量的
>>> def foo(): ... m = 0 ... def foo1(): ... m = 1 ... print m ... ... print m ... foo1() ... print m ...>>> foo()010
从执行结果可以看出,虽然在闭包里面也定义了一个变量m,但是其不会改变外部函数中的局部变量m。
2.以下这段代码是在python中使用闭包时一段经典的错误代码
def foo(): a = 1 def bar(): a = a + 1 return a return bar
这段程序的本意是要通过在每次调用闭包函数时都对变量a进行递增的操作。但在实际使用时
>>> c = foo() >>> print c() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in bar UnboundLocalError: local variable 'a' referenced before assignment
这是因为在执行代码 c = foo()时,python会导入全部的闭包函数体bar()来分析其的局部变量,python规则指定所有在赋值语句左面的变量都是局部变量,则在闭包bar()中,变量a在赋值符号"="的左面,被python认为是bar()中的局部变量。再接下来执行print c()时,程序运行至a = a + 1时,因为先前已经把a归为bar()中的局部变量,所以python会在bar()中去找在赋值语句右面的a的值,结果找不到,就会报错。解决的方法很简单
新闻热点
疑难解答