最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解析python返回函數(shù)和匿名函數(shù)

 更新時間:2022年04月29日 08:55:36   作者:礁之  
這篇文章主要介紹了python返回函數(shù)和匿名函數(shù)的相關(guān)知識,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

此文章繼續(xù)上篇高階函數(shù),地址:python函數(shù)式編程以及高階函數(shù)

一、返回函數(shù)

高階函數(shù)的特性,除了可以接受函數(shù)作為參數(shù)之外,高階函數(shù)還可以返回函數(shù)下面來看幾個案例:

1、定義一個求和的函數(shù),可以這樣寫
# -*- 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

但是如果不需要立即求和,而是需要在后面的代碼中再進(jìn)行計算改怎么辦,當(dāng)出現(xiàn)這種情況時,就可以不返回求和的結(jié)果,而是返回求和的參數(shù),修改后可以這樣寫:
# -*- 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

可以看出,當(dāng)把函數(shù)的結(jié)果賦值給f時,直接輸出f,返回的是函數(shù),只有在調(diào)用 f( ) 時,才會返回結(jié)果

看過上面的案例,還可以發(fā)現(xiàn)一件事,就是函數(shù)內(nèi)部定義函數(shù)是可以直接調(diào)用最外層函數(shù)的參數(shù)的,而在函數(shù)內(nèi)部定義的函數(shù),這種函數(shù)又叫內(nèi)部函數(shù),最外層的函數(shù)叫外部函數(shù)

1、閉包

內(nèi)部函數(shù)可以引用外部函數(shù)的參數(shù)和局部變量,當(dāng)外部函數(shù)返回內(nèi)部函數(shù)時,相關(guān)的參數(shù)和變量都保存在返回的內(nèi)部函數(shù)中,這種程序結(jié)構(gòu)又稱為“閉包(Closure)”上面的內(nèi)部函數(shù)test_sum就引用了局部函數(shù)args

需要注意的是每次調(diào)用外部函數(shù)test_1()時,每次調(diào)用都會生成一個新的函數(shù),即便傳入相同的參數(shù):

# -*- 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

可以看到,就算參數(shù)相同、返回的值相同,但是每次調(diào)用函數(shù)返回的函數(shù)是不一樣的

還需要注意的是,如果只是把返回的函數(shù)賦值給變量,那么這個函數(shù)是不會執(zhí)行的,直到調(diào)用函數(shù)才會執(zhí)行:

# -*- 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

可以發(fā)現(xiàn),連續(xù)把count函數(shù)賦值了三次變量后,引用變量時,返回的值全部都是9,這是因?yàn)榉祷睾瘮?shù) f( ) 中調(diào)用了局部變量i,而i是for循環(huán)引用的函數(shù),在賦值 count( ) 函數(shù)到變量時,因?yàn)椴]有直接調(diào)用函數(shù),所以內(nèi)部函數(shù) f( ) 其實(shí)是沒有執(zhí)行的,只是進(jìn)行了循環(huán),而賦值三次后,變量i已經(jīng)循環(huán)到了3,這時候調(diào)用了函數(shù),內(nèi)部函數(shù) f( ) 在這個時候執(zhí)行了,所以三次的結(jié)果都是9

注意:在使用閉包特性時要記住,返回函數(shù)(內(nèi)部函數(shù))不要引用任何循環(huán)變量或后續(xù)會發(fā)送變化的變量,如果一定要使用循環(huán)變量怎么辦,可以再創(chuàng)建一個函數(shù)例如:

# -*- 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

這樣寫,在函數(shù)中就調(diào)用了函數(shù)

2、nonlocal

使用閉包,即內(nèi)部函數(shù)調(diào)用了外部函數(shù)的局部變量,如果只是讀取外層函數(shù)變量的值,可以看到返回的閉包函數(shù)調(diào)用一切正常:

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

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

#輸出
1
1

但是如果要在內(nèi)部函數(shù)去修改外部函數(shù)變量的值時,會發(fā)生報錯

# -*- coding: utf-8 -*-
def inc():
    x = 0
    def fn():
        # 這里在內(nèi)部函數(shù)修改了外部函數(shù)變量的值
        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

上面的原因是因?yàn)?code>x作為局部變量是沒有初始化的,所以直接修改x變量是不行的,但是可以使用nonlocal聲明把x變量初始化,從而可以正常調(diào)用函數(shù)

# -*- coding: utf-8 -*-
def inc():
    x = 0
    def fn():
        # 先聲明x變量不是fn函數(shù)的局部變量
        nonlocal x
        x = x + 1
        return x
    return fn

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

#輸出
1
2

注意:使用閉包時,對外層變量賦值前,需要先使用nonlocal聲明該變量不是當(dāng)前函數(shù)的局部變量,從而時函數(shù)正常調(diào)用

引用一個示例:

- 利用閉包返回一個計數(shù)器函數(shù),每次調(diào)用它返回遞增整數(shù)
# -*- 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
測試通過!

#解析
其實(shí)和上面類似,利用nonlocal聲明之后可以使內(nèi)部函數(shù)修改外部函數(shù)的變量,然后返回一個函數(shù),從而實(shí)現(xiàn)每次調(diào)用遞增

二、匿名函數(shù)——lambda

  • 有些時候在傳入函數(shù)時,并不需要顯式的定義函數(shù),直接傳入匿名函數(shù)更方便
  • 而python中,對匿名函數(shù)提供了支持,以map()為例,在計算f(x)=x*x時,除了可以定義一個函數(shù)f之外,還可以直接傳入匿名函數(shù):
#使用匿名函數(shù):
>>> list(map(lambda x:x * x,[1,2,3,4,5,6]))  
[1, 4, 9, 16, 25, 36]

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

#雖然兩種方法都可以達(dá)到效果,但是可以看出匿名函數(shù)比較簡潔

從上面的例子可以看出,lambda關(guān)鍵字就表示匿名函數(shù),而前面的x就表示函數(shù)的參數(shù)匿名函數(shù)有一個限制,就是只能有一個表達(dá)式,不需要寫return返回,返回的值為表達(dá)式的結(jié)果。因?yàn)槟涿瘮?shù)不需要定義函數(shù)名稱,所以也不用擔(dān)心函數(shù)名會沖突,并且匿名函數(shù)也是一個函數(shù)對象,也就是說匿名函數(shù)也可以賦值給一個變量,通過變量來調(diào)用函數(shù),其實(shí)這個特性在之前的案例中也使用到了:

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

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

引用一個案例

- 利用匿名函數(shù)改造下面代碼,使之更為簡潔
# -*- 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]

- 改造成匿名函數(shù)后:
# -*- 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對匿名函數(shù)的支持有限,只有一些簡單的情況下可以使用匿名函數(shù)。

到此這篇關(guān)于python返回函數(shù)和匿名函數(shù)的文章就介紹到這了,更多相關(guān)python返回函數(shù)和匿名函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 舉例講解Python中的算數(shù)運(yùn)算符的用法

    舉例講解Python中的算數(shù)運(yùn)算符的用法

    這篇文章主要介紹了舉例講解Python中的算數(shù)運(yùn)算符的用法,是Python學(xué)習(xí)當(dāng)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-05-05
  • 使用python tkinter實(shí)現(xiàn)各種個樣的撩妹鼠標(biāo)拖尾效果

    使用python tkinter實(shí)現(xiàn)各種個樣的撩妹鼠標(biāo)拖尾效果

    這篇文章主要介紹了使用python tkinter實(shí)現(xiàn)各種個樣的撩妹鼠標(biāo)拖尾效果,本文通過實(shí)例代碼,給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • 實(shí)現(xiàn)python?namedtuple元類編程

    實(shí)現(xiàn)python?namedtuple元類編程

    這篇文章主要為大家介紹了實(shí)現(xiàn)python?namedtuple元類編程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Python使用pandas實(shí)現(xiàn)對數(shù)據(jù)進(jìn)行特定排序

    Python使用pandas實(shí)現(xiàn)對數(shù)據(jù)進(jìn)行特定排序

    在數(shù)據(jù)分析和處理過程中,排序是一項(xiàng)常見而重要的操作,本文將詳細(xì)介紹如何利用pandas對數(shù)據(jù)進(jìn)行特定排序,包括基本排序、多列排序、自定義排序規(guī)則等方面的內(nèi)容,需要的可以了解下
    2024-03-03
  • Python獲取二維矩陣每列最大值的方法

    Python獲取二維矩陣每列最大值的方法

    下面小編就為大家分享一篇Python獲取二維矩陣每列最大值的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python中關(guān)于面向?qū)ο蟾拍畹脑敿?xì)講解

    Python中關(guān)于面向?qū)ο蟾拍畹脑敿?xì)講解

    要了解面向?qū)ο笪覀兛隙ㄐ枰戎缹ο蟮降资鞘裁赐嬉鈨?。關(guān)于對象的理解很簡單,在我們的身邊,每一種事物的存在都是一種對象。總結(jié)為一句話也就是:對象就是事物存在的實(shí)體
    2021-10-10
  • Python實(shí)現(xiàn)快速提取Word表格并寫入Excel

    Python實(shí)現(xiàn)快速提取Word表格并寫入Excel

    在日常辦公中,常常會遇到需要從Word文檔中提取表格內(nèi)容,并將其寫入Excel表格的需求,下面我們就來看看如何使用Python實(shí)現(xiàn)快速提取Word表格并寫入Excel吧
    2024-12-12
  • Qt實(shí)現(xiàn)炫酷啟動圖動態(tài)進(jìn)度條效果

    Qt實(shí)現(xiàn)炫酷啟動圖動態(tài)進(jìn)度條效果

    最近接到一個新需求,讓做一個動效進(jìn)度條。剛接手這個項(xiàng)目真的不知所措,后來慢慢理清思路,問題迎刃而解,下面小編通過本文給大家?guī)砹薗t實(shí)現(xiàn)炫酷啟動圖動態(tài)進(jìn)度條效果,感興趣的朋友一起看看吧
    2021-11-11
  • python使用turtle庫繪制時鐘

    python使用turtle庫繪制時鐘

    這篇文章主要為大家詳細(xì)介紹了python使用turtle庫繪制時鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 使用Python中tkinter庫簡單gui界面制作及打包成exe的操作方法(二)

    使用Python中tkinter庫簡單gui界面制作及打包成exe的操作方法(二)

    這篇文章主要介紹了使用Python中tkinter庫簡單gui界面制作及打包成exe的操作方法(二),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10

最新評論

林芝县| 丰镇市| 茌平县| 聂荣县| 张北县| 九寨沟县| 子长县| 洪雅县| 苍梧县| 阳城县| 拜城县| 德阳市| 宜春市| 伊吾县| 横峰县| 江川县| 浮山县| 德化县| 策勒县| 安顺市| 阜阳市| 巨野县| 永德县| 新野县| 丽水市| 铅山县| 互助| 屯留县| 临海市| 富阳市| 高密市| 黑山县| 根河市| 辛集市| 察雅县| 鄂托克前旗| 泰和县| 沾益县| 景谷| 石屏县| 庄浪县|