广告
返回顶部
首页 > 资讯 > 后端开发 > Python >深入解析python返回函数和匿名函数
  • 584
分享到

深入解析python返回函数和匿名函数

2024-04-02 19:04:59 584人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、返回函数1、闭包2、nonlocal二、匿名函数——lambda此文章继续上篇高阶函数,地址:python函数式编程以及高阶函数 一、返回函数 高阶函

此文章继续上篇高阶函数,地址:python函数式编程以及高阶函数

一、返回函数

高阶函数的特性,除了可以接受函数作为参数之外,高阶函数还可以返回函数下面来看几个案例:


1、定义一个求和的函数,可以这样写
# -*- coding: utf-8 -*-
def test_1(*args):
    i = 0
    for n in args:
        i = i + n
    return i

print(test_1(10,20,30))

#输出
60

但是如果不需要立即求和,而是需要在后面的代码中再进行计算改怎么办,当出现这种情况时,就可以不返回求和的结果,而是返回求和的参数,修改后可以这样写:
# -*- coding: utf-8 -*-
def test_1(*args):
    def test_sum():
        i = 0
        for n in args:
            i = i + n
        return i
    return test_sum

f = test_1(10,20,30)
print(f)
print(f())

#输出
<function test_1.<locals>.test_sum at 0x0000020483CAE7A0>
60

可以看出,当把函数的结果赋值给f时,直接输出f,返回的是函数,只有在调用 f( ) 时,才会返回结果

看过上面的案例,还可以发现一件事,就是函数内部定义函数是可以直接调用最外层函数的参数的,而在函数内部定义的函数,这种函数又叫内部函数,最外层的函数叫外部函数

1、闭包

内部函数可以引用外部函数的参数和局部变量,当外部函数返回内部函数时,相关的参数和变量都保存在返回的内部函数中,这种程序结构又称为“闭包(Closure)”上面的内部函数test_sum就引用了局部函数args

需要注意的是每次调用外部函数test_1()时,每次调用都会生成一个新的函数,即便传入相同的参数:

# -*- coding: utf-8 -*-
def test_1(*args):
    def test_sum():
        i = 0
        for n in args:
            i = i + n
        return i
    return test_sum

f1 = test_1(10,20,30)
f2 = test_1(10,20,30)
print(f1)
print(f1())
print(f2)
print(f2())
if f1 == f2 :
    print("yes")
else:
    print("error")

#输出
<function test_1.<locals>.test_sum at 0x000001F27E2AE7A0>
60
<function test_1.<locals>.test_sum at 0x000001F27E2AE8C0>
60
error

可以看到,就算参数相同、返回的值相同,但是每次调用函数返回的函数是不一样的

还需要注意的是,如果只是把返回的函数赋值给变量,那么这个函数是不会执行的,直到调用函数才会执行:

# -*- coding: utf-8 -*-
def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs

f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())

#输出:
9
9
9

可以发现,连续把count函数赋值了三次变量后,引用变量时,返回的值全部都是9,这是因为返回函数 f( ) 中调用了局部变量i,而i是for循环引用的函数,在赋值 count( ) 函数到变量时,因为并没有直接调用函数,所以内部函数 f( ) 其实是没有执行的,只是进行了循环,而赋值三次后,变量i已经循环到了3,这时候调用了函数,内部函数 f( ) 在这个时候执行了,所以三次的结果都是9

注意:在使用闭包特性时要记住,返回函数(内部函数)不要引用任何循环变量或后续会发送变化的变量,如果一定要使用循环变量怎么办,可以再创建一个函数例如:

# -*- coding: utf-8 -*-
def count():
    def f(j):
        def g():
            return j * j
        return g
    fs = []
    for i in range(1,4):
        fs.append(f(i))
    return fs

f1,f2,f3 = count()
print(f1())
print(f2())
print(f3())

#输出:
1
4
9

这样写,在函数中就调用了函数

2、nonlocal

使用闭包,即内部函数调用了外部函数的局部变量,如果只是读取外层函数变量的值,可以看到返回的闭包函数调用一切正常:

# -*- coding: utf-8 -*-
def inc():
    x = 0
    def fn():
        # 可以看到这里只是读取了x的值:
        return x + 1
    return fn

f = inc()
print(f()) 
print(f()) 

#输出
1
1

但是如果要在内部函数去修改外部函数变量的值时,会发生报错

# -*- coding: utf-8 -*-
def inc():
    x = 0
    def fn():
        # 这里在内部函数修改了外部函数变量的值
        return x = x + 1
    return fn

f = inc()
print(f()) 
print(f()) 

#输出,这里直接就报错了
  File "c:\Users\RZY\Desktop\work\py\test.py", line 5
    return x = x + 1
             ^
SyntaxError: invalid syntax

上面的原因是因为x作为局部变量是没有初始化的,所以直接修改x变量是不行的,但是可以使用nonlocal声明把x变量初始化,从而可以正常调用函数

# -*- coding: utf-8 -*-
def inc():
    x = 0
    def fn():
        # 先声明x变量不是fn函数的局部变量
        nonlocal x
        x = x + 1
        return x
    return fn

f = inc()
print(f()) 
print(f()) 

#输出
1
2

注意:使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量,从而时函数正常调用

引用一个示例:

- 利用闭包返回一个计数器函数,每次调用它返回递增整数
# -*- coding: utf-8 -*-
def createCounter():
    x = 0 
    def counter():
        nonlocal x 
        x = x + 1
        return x 
    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('测试失败!')
    
#输出
1 2 3 4 5
测试通过!

#解析
其实和上面类似,利用nonlocal声明之后可以使内部函数修改外部函数的变量,然后返回一个函数,从而实现每次调用递增

二、匿名函数——lambda

  • 有些时候在传入函数时,并不需要显式的定义函数,直接传入匿名函数更方便
  • python中,对匿名函数提供了支持,以map()为例,在计算f(x)=x*x时,除了可以定义一个函数f之外,还可以直接传入匿名函数:
#使用匿名函数:
>>> list(map(lambda x:x * x,[1,2,3,4,5,6]))  
[1, 4, 9, 16, 25, 36]

#定义函数:
>>> def f(x):
...     return x * x
... 
>>> list(map(f,[1,2,3,4,5,6]))   
[1, 4, 9, 16, 25, 36]

#虽然两种方法都可以达到效果,但是可以看出匿名函数比较简洁

从上面的例子可以看出,lambda关键字就表示匿名函数,而前面的x就表示函数的参数匿名函数有一个限制,就是只能有一个表达式,不需要写return返回,返回的值为表达式的结果。因为匿名函数不需要定义函数名称,所以也不用担心函数名会冲突,并且匿名函数也是一个函数对象,也就是说匿名函数也可以赋值给一个变量,通过变量来调用函数,其实这个特性在之前的案例中也使用到了:

>>> f = lambda  x : x*x
>>> f
<function <lambda> at 0x0000020CE841E7A0>
>>> f(22) 
484

#匿名函数也可以作为函数的返回值
>>> def f(x,y):
...     return lambda: x * y    
... 
>>> a = f(5,6) 
>>> a()
30

引用一个案例

- 利用匿名函数改造下面代码,使之更为简洁
# -*- coding: utf-8 -*-
def is_odd(n):
    return n % 2 == 1

L = list(filter(is_odd, range(1, 20)))

print(L)
#输出:
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

- 改造成匿名函数后:
# -*- coding: utf-8 -*-
L = list(filter(lambda x:x % 2 ==1, range(1, 20)))

print(L)
#输出:
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

提示:Python对匿名函数的支持有限,只有一些简单的情况下可以使用匿名函数。

到此这篇关于python返回函数和匿名函数的文章就介绍到这了,更多相关python返回函数和匿名函数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 深入解析python返回函数和匿名函数

本文链接: https://www.lsjlt.com/news/117558.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 深入解析python返回函数和匿名函数
    目录一、返回函数1、闭包2、nonlocal二、匿名函数——lambda此文章继续上篇高阶函数,地址:python函数式编程以及高阶函数 一、返回函数 高阶函...
    99+
    2022-11-10
  • Pythonlambda匿名函数深入讲解
    目录一,Python中lambda函数的语法二,两个注意点三,lambda 应用一,Python中lambda函数的语法 lambda 函数在 Python 编程语言中使用频率非常高...
    99+
    2023-01-28
    Python lambda匿名函数 Python lambda Python匿名函数
  • php如何返回匿名函数并给匿名函数传参
    这篇文章主要介绍了php如何返回匿名函数并给匿名函数传参,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。返回匿名函数并给匿名函数传参<p...
    99+
    2022-10-19
  • 浅谈Python函数式编程的返回函数与匿名函数
    目录返回函数匿名函数返回函数 所谓返回函数,顾名思义,就是把函数作为返回值。高阶函数除了可以将函数作为参数之外,还可以将函数作为结果进行返回。下面来实现一个可变参数的连乘,求积函数可...
    99+
    2023-05-15
    Python函数 Python函数式 Python返回函数 Python匿名函数
  • Python函数式编程的返回函数与匿名函数怎么定义
    本篇内容介绍了“Python函数式编程的返回函数与匿名函数怎么定义”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!返回函数所谓返回函数,顾名思...
    99+
    2023-07-06
  • Python技巧匿名函数、回调函数和高阶函数
    目录1、定义匿名或内联函数 2、在匿名函数中绑定变量的值 3、让带有n个参数的可调用对象以较少的参数调用 4、在回调函数中携带额外的状态 1、定义匿名或内联函数 如果我们想提供一个...
    99+
    2022-11-12
  • python函数和python匿名函数lambda详解
    目录1. python函数1.1 函数的作用1.2 函数定义1.3 函数调用1.4 函数的参数1.4.1 参数的传递1.4.2 参数类型1.4.2.1 位置参数(必备参数)1.4.2...
    99+
    2022-11-11
  • python之高阶函数和匿名函数
    map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。 1 def func(x): 2 return x*x 3 4 r = ma...
    99+
    2023-01-30
    函数 高阶 python
  • python中lambda匿名函数详解
    在Python中,不通过def来声明函数名字,而是通过lambda关键字来定义的函数称为匿名函数 关键字lambda表示匿名函数 语法 lambda 参数:表达式 先写lambda关...
    99+
    2022-11-13
  • 【Python基础】- 自定义函数和匿名函数
      🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬...
    99+
    2023-09-01
    python 开发语言
  • Python浅析匿名函数lambda的用法
    目录lambda函数的定义   Lambda函数在Python中lambda函数的定义    lambda函数是Pytho...
    99+
    2022-11-11
  • python基础之匿名函数详解
    目录1.匿名函数介绍2.语法3.使用场景4.匿名函数和普通函数的对比5.匿名函数的多种形式6.lambda 作为一个参数传递7. lambda函数与python内置函数配合使用8.l...
    99+
    2022-11-12
  • JavaScript函数语法、函数调用和函数返回实例分析
    这篇文章主要介绍了JavaScript函数语法、函数调用和函数返回实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript函数语法、函数调用和函数返回实例分析...
    99+
    2022-10-19
  • C++深入分析回顾函数重载
    目录一、函数重载回顾二、类中的重载三、重载的意义四、小结一、函数重载回顾 函数重载的本质为相互独立的不同函数C++ 中通过函数名和函数参数确定函数调用无法直接通过函数名得到重载函数的...
    99+
    2022-11-13
  • python基础之引用和匿名函数
    a=1 #1 为对象, def func(x): print('x的地址{}'.format(id(x))) x=2 print('x的地址{}'...
    99+
    2022-11-12
  • Python函数式编程之返回函数实例详解
    目录看代码:用filter函数来计算素数用Python高阶函数来实现这个算法:高阶函数实现打印小于100的素数:总结 高阶函数除了可以接受函数作为参数外,还可以把函数作为结...
    99+
    2022-11-11
  • 深入了解python的函数参数
    目录位置参数默认参数关键字参数多值参数:总结 位置参数 这是一个求等差数列和的函数,使用必需要传入一个参数n,这就是位置参数 def sum(n): sum=0 ...
    99+
    2022-11-12
  • python教程之生成器和匿名函数
    目录生成器01 什么是生成器?02 通俗的讲解03 生成器到底有什么用?04 生成器的常见用途?匿名函数01 什么是匿名函数?02 通俗的讲解总结生成器 01 什么是生成器? 记住两...
    99+
    2022-11-12
  • Pythonlambda匿名函数优点和局限性深度总结
    目录什么是 Python 中的 Lambda 函数Python 中的 Lambda 函数如何工作Lambda 函数在 Python 中的应用带有 filter() 函数的 Lambd...
    99+
    2022-11-11
  • Golang函数的命名返回值专题详解
    Golang作为一门向并发领域发展的编程语言,为了让开发者更加方便地处理数据和状态,设计了一些非常方便实用的特性和语法,其中包括函数的命名返回值。在本文中,我们将深入探讨这个特性的使用方法和注意事项。一、命名返回值的概念在函数中,我们经常需...
    99+
    2023-05-16
    函数 Golang 命名返回值
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作