Python学习笔记__4.2章 返回函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习笔记__4.2章 返回函数相关的知识,希望对你有一定的参考价值。

# 这是学习廖雪峰老师python教程的学习笔记

1、函数作为返回值

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

# 累加函数

def external(*args):

    def internal():

        ax = 0

        for n in args:

            ax = ax + n

        return ax

    return internal  # external的返回值是internal

 

# 调用external()

f = external(1, 3, 5, 7, 9)   #这里的 f是一个函数,相当于internalexternal 函数的参数会传给internal

>>> f()  # 调用函数,==inernal()

25

 

在函数 external 中又定义了函数inernal,并且,内部函数inernal 可以引用外部函数external 的参数和局部变量当external 返回函数internal 时,相关参数和变量都保存在返回的函数中,这样的程序我们称为 闭包

注:,每次调用 external 都会返回一个新的函数,即使传入相同的参数

 

2、闭包

2.1、理解闭包-1

在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例

2.2、理解闭包-2

在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量则可能产生闭包。运行时,一旦外部的 函数被执行,一个闭包就形成了闭包中包含了内部函数的代码,以及所需外部函数中的变量的引用。其中所引用的变量称作上值(upvalue)

2.3、理解闭包-3

Python 中通俗一点来说,如果在一个函数内部,嵌套了函数,这个内部函数对(非全局作用域)外部作用域的变量进行引用,那么这个内部函数称为闭包。闭包每次运行都能记住引用的外部作用域的变量的值。

2.4、个人理解

  • 外部函数执行完毕,返回内部函数后即消失。#      external(1,3,5,7) 执行完毕,返回internal

  • 此时,外部函数里定义的变量依然会和内部函数一同存在。#  external函数传入的参数      args=[1,3,5,7],同internal 一起存在

  • 变量和内部函数组成一个环境。 #      interal

  • interal函数起个‘别名’ #  f = external(1, 3,      5, 7, 9)   f == internal

  • 执行 internal 函数 # f()

2.5、实例分析

1f f()

def count():

    fs = []

    for i in range(1, 4):

        def f():

             return i*i

        fs.append(f)    # 注意这里,fs.append 的是一个函数

    return fs

 

f1, f2, f3 = count()

                    1、fs.append(f)

  • 外部函数count 的返回值是 fs。

  • fs 是一个list。list里是 f 函数。

  • f1, f2, f3 =      count(),即 f1,f2,f3 = f 。 调用时 f()的结果就是 f(3)

  • f 函数外是一个for循环。fs里调用的是 f 函数,for循环的中间值无处可存,最后 fs=[f(3),f(3),f(3)]

                            2、fs.append(f())

  • 如果把 f 换成 f() 呢?

  • 此时fs.append的就是算好的值,返回的fs就是 fs=[1,4,9],不再有闭包

  • f1, f2, f3 =      count(),即 f1=1 , f2=4 , f3=9

 

# 在闭包中使用循环变量

def count():

    def f(j):         引入 f() 函数 ,使得 for 循环的 中间值得以保存

        def g():

            return j*j

        return g

    fs = []

    for i in range(1, 4):

        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入fs

    return fs

f1, f2, f3 = count()

 

f1() == f(1)

f2() == f(2)

f3() == f(3)

 

3、作用域

python内的作用域有:

  1. 本地作用域(Local)   # 函数内部定义的

  2. 嵌套作用域(Enclosing function      locals)  #  外层函数的 参数a ,内层函数引用a时,就是从嵌套作用域中拿

  3. 全局作用域(Global)   # 函数体外 定义的

  4. 内置作用域(buitins模块)   # 编译层内置的

python在引用一个变量时,对这个变量的搜索 从 1) --》 4)

3.1、函数内修改全局变量

x = 99

def func()

    global x             #  global 告诉 函数,这里的x 是全局变量。你不要在 自己的 本地作用域 创建 x 变量了

    x = 88

3.2、内层函数 修改 嵌套域变量

def func():

    count = 1

    def foo():

        nonlocal count    # nonlocal 告诉 内置函数foo(),这里引用的是外层函数的count 变量,你不要在 自己的 本地作用域创建变量了

        count = 12

    foo()

    print(count)

 

4、例子

1、利用闭包返回一个计数器函数,每次调用它返回递增整数:

# -*- coding: utf-8 -*-

 

def createCounter():

    n=0

    def counter():

        nonlocal n         #  指明引用的n 不是函数内部定义的

        n+=1

        return n

    return counter

 

 

 

# 测试:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('测试通过!')
else:
    print('测试失败!')


以上是关于Python学习笔记__4.2章 返回函数的主要内容,如果未能解决你的问题,请参考以下文章

Python学习笔记__4.5章 偏函数(绑定函数参数)

Python学习笔记__4.3章 匿名函数(简洁函数)

Python学习笔记__4.1.3章 sorted

Python学习笔记__4.1.2章 filter

Python学习笔记__4.4章 装饰器(添加额外功能)

Python学习笔记__12.8章 contextlib