一、高階函數(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ù)的返回值
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))