第十天:高階函數(shù)吨述、迭代器岩睁、裝飾器

一、高階函數(shù)

定義:

將函數(shù)作為參數(shù)的函數(shù)揣云,即是高階函數(shù)

1.函數(shù)作為 變量

python中聲明函數(shù)就是聲明一個類型是function的變量捕儒,函數(shù)名就是變量名普通變量能做的事情函數(shù)都可以做

1.1聲明函數(shù)就是聲明變量,函數(shù)名就是變量名

1.2普通變量能做的函數(shù)都可以做

1.2.1 一個變量可以給另外一個變量賦值

a = 100
b = a
print(b, b+10)


def func3():
    print('函數(shù)3')
    return 200


b2 = func3
print(type(b2), b2())

1.2.2 修改變量的值

a = 'abc'
print(a, a[1:])

func3 = [10, 20]
# func3()   # TypeError: 'list' object is not callable
func3.append(100)
print(func3)

1.2.3 變量作為序列元素

a = 10
list1 = [a, 100, 'abc']
print(list1)


def func4():
    print('函數(shù)4')
    return 400

list2 = [func4, func4(), 10]  # list2 = [func4的地址邓夕,400刘莹,10]
print(list2)
print(list2[0]())    # func4()

1.2.4 將函數(shù)作為函數(shù)的參數(shù) - 實參高階函數(shù)

def func6(x):
    # x = func4
    y = x()  # func4()
    # print('y:', y)
    return y


# func6(a)   # TypeError: 'int' object is not callable
re = func6(func4)
print(re)

1.2.5 系統(tǒng)的實參高階函數(shù)

列表.sort()、sorted()翎迁、max()栋猖、min()都是實參高階函數(shù), 因為這四個函數(shù)中都有一個參數(shù)key,要求是一個函數(shù)
1.2.5.1 排序方法
參數(shù)key要求是一個函數(shù)汪榔,作用是用來定制排序的規(guī)則(默認(rèn)按元素的大小從小到大或者從大到小排序)
"""
參數(shù)key的要求:
a.key是一個函數(shù)
b.函數(shù)中有且只有一個參數(shù), 這個參數(shù)指向的是序列中的每個元素
c.函數(shù)需要一個返回值,這個返回值就是排序的時候比較大小的對象
"""
# 練習(xí): 將nums中的元素按個位數(shù)從小到大排序
nums = [100, 39, 51, 62, 58]
# nums = [100, 51, 62, 58, 39]


# def func_key(item):
#     return item % 10
# func_key = lambda item: item % 10

nums.sort(key=lambda item: item % 10)
print(nums)

二肃拜、返回值高階函數(shù)

1.變量可以作為函數(shù)的返回值

def yt_sum(x, y):
    # x=10, y=20
    t = x+y   # t = 10+20 = 30
    return t  # return 30


print(yt_sum(10, 20))

2.返回值高階函數(shù) --- 函數(shù)作為函數(shù)的返回值

  • func1就是以一個返回值高階函數(shù)
def func1():
    def func2():
        print('函數(shù)2')

    return func2

3.閉包

函數(shù)1中聲明了一個函數(shù)2痴腌,并且在函數(shù)2中使用了函數(shù)1的數(shù)據(jù),那么這個函數(shù)1就是一個閉包

3.1 閉包的特點

閉包函數(shù)中的數(shù)據(jù)不會因為函數(shù)調(diào)用結(jié)束而銷毀
def func3():
    a = 10
    print(id(a))

    def func4():
        print(a)
        print(id(a))

    return func4


t = func3()
t()   # 10

4.經(jīng)典面試題

# 面試題1:
list1 = []
for i in range(5):
    list1.append(lambda x: x*i)

# list1 = [lambda x: x*i, lambda x: x*i, lambda x: x*i, lambda x: x*i, lambda x: x*i]
# i = 4
print(list1[1](2), list1[2](2), list1[3](2))  #結(jié)果8燃领,8士聪,8


# def func10():
#     print(yyy + 100)


# 面試題2: 函數(shù)參數(shù)默認(rèn)值
def func2(seq=[]):
    # seq = []
    seq.append(10)   # [10]
    return seq


print(func2())  # [10]
print(func2())  # [10, 10]

# 練習(xí): 寫出打印結(jié)果
list3 = [1, 2]


def func3(seq=list3):
    # seq=seq
    seq.append(10)
    return seq


func3()
# list3 = [100, 200]
list3.append(100)
print(func3())

三、裝飾器

1.什么是裝飾器

"""
裝飾器本質(zhì)是一個函數(shù) = 返回值高階函數(shù)+實參高階函數(shù)+糖語法
裝飾器是python的三大神器之一: 裝飾器猛蔽、迭代器剥悟、生成器
作用: 給已經(jīng)寫好的函數(shù)添加新的功能
"""
"""
無參裝飾器的函數(shù):
def 函數(shù)名1(參數(shù)1):
    def 函數(shù)名2(*args, **kwargs):
        result = 參數(shù)1(*args, **kwargs)
        新功能對應(yīng)的代碼段
        return result
    return 函數(shù)名2
    
說明: 
函數(shù)名1  -  裝飾器的名字;一般根據(jù)需要添加的功能命名
參數(shù)1 - 需要添加功能的函數(shù), 一般命名為fn
函數(shù)名2  -  隨便命名, 可以用test
"""

2.例

def add_time3(fn):

    def test(*args, **kwargs):
        start = time.time()
        re = fn(*args, **kwargs)
        end = time.time()
        print('函數(shù)執(zhí)行時間: %fs' % (end - start))
        return re

    return test


@add_time3
def func5():
    print('你好嗎')


func5()

3.練習(xí)

給所有返回值是整數(shù)的函數(shù)添加功能: 返回值以16進(jìn)制形式的數(shù)據(jù)返回
def add_hex(fn):
    def test(*args, **kwargs):
        re = fn(*args, **kwargs)
        # type(re) == int
        # 判斷re是否是整型
        if isinstance(re, int):
            return hex(re)
        return re
    return test


@add_hex
def yt_sum(x, y):
    return x+y


print(yt_sum(10, 20))

四曼库、迭代器

1.定義

"""
迭代器也是python提供的容器型數(shù)據(jù)類型

迭代器存儲數(shù)據(jù)的特點: 一個迭代器可以存儲多個數(shù)據(jù)区岗,如果要獲取元素必須將元素從迭代器中取出,而且取一個就少一個毁枯;
取出來的數(shù)據(jù)不能再添加到迭代器中

"""

2.將數(shù)據(jù)存入迭代器中

2.1 將別的序列轉(zhuǎn)換成迭代器

list1 = [10, 20, 30, 40]
iter1 = iter(list1)
print(iter1)   # <list_iterator object at 0x110190400>
# print(len(iter1))   # TypeError: object of type 'list_iterator' has no len()

iter2 = iter('hello')
print(iter2)    # <str_iterator object at 0x109be0550>

3.獲取迭代器中的元素

"""
迭代器中的元素不同通過什么方式取出來了慈缔,那么這個元素在迭代器中就不存在了

1)獲取單個元素:
next(迭代器)  -> 取出迭代器中最前面的元素
"""

遍歷 - 一個一個的取所有的元素
for x in iter2:
    print('x:', x)

作業(yè)

#1.為函數(shù)寫一個裝飾器,在函數(shù)執(zhí)行之后輸出 after
def add_after(fn):
    def test(*args, **kwargs):
        fn(*args, **kwargs)
        print('after')

    return test

@add_after
def yh_test():
    print('我不需要after')

yh_test()

#2.為函數(shù)寫一個裝飾器种玛,把函數(shù)的返回值 +100 然后再返回藐鹤。

def add_num(fn):
    def test(*args,**kwargs):
        re = fn(*args, **kwargs)
        return re + 100
    return test

@add_num
def yh_sum(x, y):
    return x + y

print(yh_sum(100, 200))

#3.寫一個裝飾器@tag要求滿足如下功能:

def tag(fn):
    def test(*args,**kwargs):
       re =  fn(*args, **kwargs)
       return '<p>' + re + '</p>'
    return test

@tag
def render(text):
    return text

@tag
def render2():
    return 'abc'

print(render('hello'))
print(render2())

# 4.寫一個裝飾器@tag要求滿足如下功能(需要使用帶參的裝飾器瓤檐,自己先自學(xué)正在一下):
def tag(string):
    def add_str(fn):
        def test(*args, **kwargs):
            re = fn(*args, **kwargs)
            return '<' + string + '>' + re + '</' + string + '>'
        return test
    return add_str

@tag(string = 'p')
def render3(text):
    return text

@tag('div')
def render4():
    return 'abc'

print('=========================')
print(render3('hello'))
print(render4())

# 5.為函數(shù)寫一個裝飾器,根據(jù)參數(shù)不同做不同操作

def flag(bool):
    def add_sum1(fn):
        def test(*args, **kwargs):
            re = fn(*args, **kwargs)
            if bool:
                return re + 100
            else:
                return re - 100
        return test
    return add_sum1

@flag(bool = False)
def sum2(x, y):
    return x + y

@flag(bool = True)
def sum3(x, y):
    return x + y

print('=========================')
print(sum2(100, 200))
print(sum3(100, 200))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末娱节,一起剝皮案震驚了整個濱河市挠蛉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肄满,老刑警劉巖碌秸,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悄窃,居然都是意外死亡讥电,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門轧抗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恩敌,“玉大人,你說我怎么就攤上這事横媚【琅冢” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵灯蝴,是天一觀的道長恢口。 經(jīng)常有香客問我,道長穷躁,這世上最難降的妖魔是什么耕肩? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮问潭,結(jié)果婚禮上猿诸,老公的妹妹穿的比我還像新娘。我一直安慰自己狡忙,他們只是感情好梳虽,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灾茁,像睡著了一般窜觉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上北专,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天禀挫,我揣著相機與錄音,去河邊找鬼逗余。 笑死特咆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播腻格,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼画拾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了菜职?” 一聲冷哼從身側(cè)響起青抛,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酬核,沒想到半個月后蜜另,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡嫡意,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年举瑰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔬螟。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡此迅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出旧巾,到底是詐尸還是另有隱情耸序,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布鲁猩,位于F島的核電站坎怪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏廓握。R本人自食惡果不足惜搅窿,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疾棵。 院中可真熱鬧戈钢,春花似錦、人聲如沸是尔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拟枚。三九已至,卻和暖如春众弓,著一層夾襖步出監(jiān)牢的瞬間恩溅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工谓娃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留脚乡,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像奶稠,于是被迫代替她去往敵國和親俯艰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354