`
xiaoyu966
  • 浏览: 258168 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

python之嵌套函数与闭包

阅读更多

函数基础

关于函数基础,可以查看我的另一篇博客:http://yunjianfei.iteye.com/blog/2186064

与本文相关的,有两个重要概念:变量作用域(scope)与生命周期(lifetime

如果对于这两个概念有所疑惑,可以先去了解一下。

 

嵌套函数

python是允许创建嵌套函数的,也就是说我们可以在函数内部定义一个函数,这些函数都遵循各自的作用域和生命周期规则。

 

#!/usr/bin/env python

def outer():
    x = 1
    def inner():
        print x # 1
    inner() # 2

outer()

 输出结果:

 

1

 这个例子比普通的函数定义看起来复杂了一点,实际上都是很合理的。

 

1. #1的地方,python寻找名为x的local变量,在inner作用域内的locals中寻找不到,python就在外层作用域中寻找,其外层是outer函数。x是定义在outer作用域范围内的local变量。

2.  #2的地方,调用了inner函数。这里需要特别注意:inner也只是一个变量名,是遵循python的变量查找规则的(Python先在outer函数的作用域中寻找名为inner的local变量)

 

函数在python中是first-class对象

上面这句话看着有点抽象,简单点来说,在python中所有的东西都是对象,函数也是对象,看下面的代码:

 

#!/usr/bin/env python

a = 1
print a.__class__
print issubclass(a.__class__, object) # all objects in Python inherit from a common baseclass

def foo():
    pass

print foo.__class__ # 1
print issubclass(foo.__class__, object)

 输出结果:

<type 'int'>
True
<type 'function'>
True

 可以看到foo和变量a一样,都是顶级父类object的子类。a是一个int变量,foo是一个函数。

 

所以,函数没有什么特殊的,它和python里的其他东西一样,都属于对象,其父类是object。这意味着,

1. 函数和其他变量是一样,变量是可以传递和修改值的,函数也可以作为变量

2. 函数也可以作为函数的参数或者函数的返回值。

如下的例子:

 

#!/usr/bin/env python

def add(x, y): 
    return x + y 
def sub(x, y): 
    return x - y 
def apply(func, x, y): # 1 
    return func(x, y) # 2 

print apply(add, 2, 1) # 3

print apply(sub, 2, 1)

 执行结果

 

3
1

 这个例子中,add和sub就是两个普通的函数对象。#1中,func这个参数用来接收函数变量(和其他参数接收变量一样)。在#2处,用来执行func参数传递进来的函数。在#3处,我们把add函数作为参数传递给apply,在apply中执行,并返回结果。

 

再看一个例子:

 

#!/usr/bin/env python

def outer():
    def inner():
        print "Inside inner"
    return inner # 1

foo = outer() #2

print foo
foo()

 输出结果:

 

<function inner at 0xda38140>
Inside inner

 1. 在#1处, 我们返回了inner变量(这个变量是函数标签)。

      注意:这里并没有去调用inner,调用的话是inner()

2. 在#2处,我们将outer函数返回的结果赋值给foo变量,foo返回的是inner函数的标签(注意输出结果),       概念类似c语言中的函数指针

3. 最后执行foo的时候,实际上执行的是inner。

 

以上的例子充分说明,函数完全可以看做是变量,可以把它赋值给其他变量,且有变量作用域、变量生存周期等。

 

闭包(Closures)

再来看一个例子:

 

#!/usr/bin/env python

def outer():
    x = 1
    def inner():
        print x # 1
    return inner
foo = outer()
print foo.func_closure #2 doctest: +ELLIPSIS

foo()

 输出结果:

 

(<cell at 0x189da2f0: int object at 0x188b9d08>,)
1

 

在这个例子中,我们可以看到inner函数作为返回值被outer返回,然后存储在foo变量中,我们可以通过foo()来调用它。但是真的可以跑起来吗?让我们来关注一下作用域规则。

 

python里运行的东西,都按照作用域规则来运行。

1. x是outer函数里的local变量

2. 在#1处,inner打印x时,python在inner的locals中寻找x,找不到后再到外层作用域(即outer函数)中寻      找,找到后打印。

 

看起来一切OK,那么从变量生命周期(lifetime)的角度看,会发生什么呢:

1. x是outer的local变量,这意味着只有outer运行时,x才存在。那么按照python运行的模式,我们不能在         outer结束后再去调用inner。

2. 在我们调用inner的时候,x应该已经不存在了。应该发生一个运行时错误或者其他错误。

但是这一些都没有发生,inner函数依旧正常执行,打印了x。

 

Python支持一种特性叫做函数闭包(function closures):在非全局(global)作用域中定义inner函数(即嵌套函数)时,会记录下它的嵌套函数namespaces(嵌套函数作用域的locals),可以称作:定义时状态,可以通过func_closure 这个属性来获得inner函数的外层嵌套函数的namespaces。(如上例中#2,打印了func_closure ,里面保存了一个int对象,这个int对象就是x)

 

注意:每次调用outer函数时,inner函数都是新定义的。上面的例子中,x是固定的,所以每次调用inner函数的结果都一样。

 

下面我们看一个不同的例子:

 

#!/usr/bin/env python

def outer(x):
    def inner():
        print x # 1
    return inner
print1 = outer(1)
print2 = outer(2)
print print1.func_closure
print1()
print print2.func_closure
print2()

 输出结果:

 

(<cell at 0x147d3328: int object at 0x146b2d08>,)
1
(<cell at 0x147d3360: int object at 0x146b2cf0>,)
2

 在这个例子中,我们能看到闭包实际上是记录了外层嵌套函数作用域中的local变量。通过这个例子,我们可以创建多个自定义函数。

 

思维扩展一下,上面这个例子,很容易让人想到面向对象编程:

1. outer是inner的构造器

2.x是inner的一个私有变量

 

这里主要是帮助读者理解闭包的概念,

 

下面附上几个链接,帮助更好的理解:

http://ynniv.com/blog/2007/08/closures-in-python.html

http://www.shutupandship.com/2012/01/python-closures-explained.html

 

0
0
分享到:
评论

相关推荐

    python编程嵌套函数实例代码

    在Python编程中,函数嵌套是一...总结来说,Python中的嵌套函数可以增强代码的封装性和可读性,而闭包则使得我们可以保持一些函数状态,即便是在函数外部。掌握函数嵌套和闭包对于编写高效、优雅的Python代码至关重要。

    Python进阶——高阶函数、嵌套函数、闭包

    本文将深入探讨Python中的高阶函数、嵌套函数和闭包这三种高级概念。 **第一部分:函数对象** 在Python中,函数是第一类对象,这意味着你可以像操作其他数据类型一样操作函数。你可以将函数赋值给变量,就像给整数...

    python中的闭包函数

    闭包是函数式编程中的一个重要概念,在Python中通过嵌套函数实现闭包。闭包的主要作用是使一个内层函数能够记住并访问外层函数的作用域,即使外层函数执行完毕后,内层函数仍然可以使用外层函数的局部变量。 在...

    python中factor函数-Python基础教程.pdf

    3. **函数嵌套与闭包**: - Python支持函数嵌套,即一个函数可以定义在另一个函数内部。内部函数可以访问外部函数的局部变量,这被称为非局部作用域。 - 当内部函数引用了外部函数的局部变量,并且外部函数返回这...

    Python 之嵌套作用域.docx

    Python 之嵌套作用域是指在 Python 语言中,函数可以嵌套定义,并且每个函数都有其自己的作用域。在这个作用域中,变量的名称是唯一的,但在不同的函数中,可以有相同的变量名称,不会相互影响。 Python 之嵌套...

    python中嵌套函数的实操步骤

    在Python中,嵌套函数通常与闭包有关。闭包是指一个函数记住并能访问其词法作用域内的非局部变量,即使在其父函数已经退出后仍然可以访问。在上面的例子中,`inner_concatenate`就是一个闭包,因为它记住了`addstr`...

    python 函数 函数的偏函数 高阶函数 返回函数 匿名函数 闭包.md

    闭包是在函数嵌套的背景下产生的概念,涉及到了外部函数与内部函数之间的变量共享问题。 ##### 概念 闭包是指在函数嵌套的前提下,内部函数引用了外部函数的局部变量(包括参数),并且外部函数将内部函数作为...

    7-8-python递归+嵌套函数+OS模块文件处理

    这种特性使得嵌套函数在处理私有辅助函数或者实现闭包时非常有用。例如,在文件操作中,我们可能需要一个内部函数来处理特定的文件内容,而这个函数只在外部函数中被调用。 接着,Python的`os`模块提供了许多与操作...

    对Python闭包与延迟绑定的方法详解

    闭包必须返回嵌套函数。 嵌套函数必须引用一个外部的非全局的局部自由变量。 举个栗子 # 嵌套函数但不是闭包 def nested(): def nst(): print('i am nested func %s' % nested.__name__) nst() # 闭包函数 def ...

    Python函数嵌套实例

    在Python中函数可以作为参数进行传递,而也可以赋值给其他变量(类似Javascript,或者C/C++中的函数指针); 类似Javascript,Python支持函数嵌套,Javascript...与嵌套函数紧密相关的就是闭包特性,举一个简单的例子

    Python学习之路——函数的闭包与装饰器

    在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不...

    python 函数嵌套及多函数共同运行知识点讲解

    闭包是一种特殊的嵌套函数,它能记住其定义时的环境,即使外部函数已经执行完毕。这意味着闭包可以访问外部函数的局部变量,即使该函数已经返回。以下是一个闭包的例子: ```python def outer(): x = 10 def ...

    python中闭包Closure函数作为返回值的方法示例

    在Python中,闭包通常由嵌套函数和对外部变量的引用组成。 一、函数作为返回值 在Python中,函数是可以当作值来使用的,这意味着我们可以将函数作为参数传递给其他函数,也可以从一个函数中返回另一个函数。下面是...

    Python高级特性之闭包与装饰器实例详解

    本文实例讲述了Python高级特性之闭包与装饰器。分享给大家供大家参考,具体如下: 闭包 1.函数参数: (1)函数名存放的是函数的地址 (2)函数名()存放的是函数内的代码 (3)函数名只是函数代码空间的引用,当函数名...

    实例详解Python装饰器与闭包

    闭包是Python装饰器的基础。要理解闭包,先要了解Python中的变量作用域规则。 变量作用域规则 首先,在函数中是能访问全局变量的: ...上面的嵌套函数就是闭包。 闭包 是指延伸了作用域的函数,在其中能够访问未在

    Python 闭包,函数分隔作用域,nonlocal声明非局部变量操作示例

    本文实例讲述了Python 闭包,函数分隔作用域,nonlocal声明非局部变量操作。分享给大家供大家参考,具体如下: 实例对象也可以实现闭包的功能,不过实例对象消耗的资源(内存)比闭包多。 demo.py(闭包): # 闭包,...

    Python 高级函数实训

    #### 一、闭包与计算平方根 闭包是一种特殊的函数类型,它能够访问其外部作用域内的变量。在Python中,闭包通常由以下三个特征构成: 1. **存在于两个嵌套关系的函数中**:意味着闭包是由外部函数返回的内部函数。...

    python 函数的嵌套 详解 课件

    Python中的函数嵌套是一种高级特性,它允许在一个函数内部定义另一个函数。这种技术在处理复杂的逻辑或者封装特定功能时非常有用。下面我们将深入探讨函数嵌套的各个方面。 1. **嵌套定义** 在Python中,你可以...

Global site tag (gtag.js) - Google Analytics