高階函數(shù)定義
- 函數(shù)可以作為普通變量宾添、參數(shù)啄巧、返回值等等
- 數(shù)學(xué)概念 y = g( f( x ) )
- 在數(shù)學(xué)和計(jì)算機(jī)科學(xué)中驰贷,高階函數(shù)應(yīng)當(dāng)是最少滿足下面一個(gè)條件的函數(shù)
- 接受一個(gè)或多個(gè)函數(shù)作為參數(shù)
- 輸出一個(gè)函數(shù)
自定義sort函數(shù)
def sort(iterable, reverse=False, key=lambda x,y: x<y):
ret = []
for x in iterable:
for i,y in enumerate(ret):
flag = key(x,y) if not reverse else not key(x,y)
if flag:
ret.insert(i,x)
break
else:
ret.append(x)
return ret
print(sort([4,7,2,9,1,6]))
內(nèi)建函數(shù)-高階函數(shù)
-
filter(function, iterable)
- 過濾可迭代對(duì)象的元素鲸睛,返回一個(gè)迭代器
- function 一個(gè)具有一個(gè)參數(shù)的函數(shù)颠猴,返回bool
- 例如:過濾出數(shù)列中被3整除的數(shù)字
- list( filter( lambda x: x%3==0, [1,9,45,36,-3,86,47,96] ) )
-
map(function,
- 對(duì)多個(gè)可迭代對(duì)象的元素按照指定的函數(shù)進(jìn)行映射关划,返回一個(gè)迭代器
- list( map( lambda x: 2*x+1, range(5) ) )
- dict( map( lambda x: (x%5,x), range(500) ) )
- list( map( lambda x,y: x+y, [1,2,3,4,5], [2,3,4,5,6] ) )
- 對(duì)多個(gè)可迭代對(duì)象的元素按照指定的函數(shù)進(jìn)行映射关划,返回一個(gè)迭代器
柯里化Currying
- 柯里化(Currying)指的是將原來接受兩個(gè)參數(shù)的函數(shù)變成新的接受一個(gè)參數(shù)的函數(shù)的過程。新的函數(shù)返回一個(gè)以原有第二個(gè)參數(shù)為參數(shù)的函數(shù)翘瓮。
- z = f(x, y) 轉(zhuǎn)換成 z = f(x)(y)
# 將加法函數(shù)柯里化
def add(x,y):
return x + y
# 轉(zhuǎn)換如下
def add(x):
def _add(y):
return x + y
return _add
add(5)(6)
函數(shù)注解 Function Annotaions
- 對(duì)函數(shù)的參數(shù)贮折、返回值進(jìn)行類型注解
- 只對(duì)函數(shù)參數(shù)做一個(gè)輔助的說明,并不對(duì)函數(shù)的參數(shù)進(jìn)行類型檢查
- 函數(shù)注解的信息资盅,保存在annotaions 屬性中
- python3.6 引入 i:int = 3
add.__annotations__
{'x': <class 'int'>, 'y': <class 'str'>, 'return': <class 'str'>}
- 函數(shù)參數(shù)的檢查调榄,一定是在函數(shù)外
- 函數(shù)應(yīng)該作為參數(shù),傳入到檢查函數(shù)中
- 檢查函數(shù)拿到函數(shù)傳入的實(shí)際參數(shù)呵扛,與形參聲明對(duì)比
- annotaions 屬性是一個(gè)字典每庆,其中包括返回值類型的聲明,假設(shè)要做位置參數(shù)的判斷今穿,無法和字典中的聲明對(duì)比缤灵。使用inspect模塊
inspet模塊 -> 提供獲取對(duì)象信息的函數(shù),可以檢查函數(shù)和類蓝晒、類型檢查
inspect(callable) 獲取簽名(函數(shù)簽名包含了一個(gè)函數(shù)的信息腮出,包含函數(shù)名、它的參數(shù)類型芝薇、它所在的類和名稱空間及其他信息)
import inspect
def add(x:int, y:int, *args, **kwargs) -> int:
return x + y
sig = inspect.signature(add)
print(sig, type(sig))
>>> 函數(shù)簽名 (x:int, y:int, *args, **kwargs) -> int <class 'inspect.Signature'>
print('params:',sig.parameters)
>>> params: OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">), ('args', <Parameter "*args">), ('kwargs', <Parameter "**kwargs">)])
print('return:',sig.return_annotation )
>>> return: <class 'int'>
print(sig.parameters['x'],type(sig.parameters['x']))
>>> x:int <class 'inspect.Parameter'>
print(sig.parameters['y'].annotation)
>>> <class 'int'>
print(sig.parameters['args'],type(sig.parameters['args']))
>>> *args <class 'inspect.Parameter'>
print(sig.parameters['args'].annotation)
>>> <class 'inspect._empty'>
print(add.__annotations__)
>>> {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'str'>}
print(sig.parameters['kwargs'])
>>> **kwargs
print(sig.parameters['kwargs'].annotation)
>>> <class 'inspect._empty'>
- inspect.isfunction(add) # 是否是函數(shù)
- inspect.ismethod(add) # 是否是類的方法
- inspect.isgenerator(add) # 是否是生成器對(duì)象
- inspect.isgeneratorfunction(add) # 是否是生成器函數(shù)
- inspect.isclass(add) # 是否是類
- inspect.ismodule(add) # 是否是模塊
- inspect.isbuiltin(add) # 是否是內(nèi)建對(duì)象
- Parameter 對(duì)象
- 保存在元組中胚嘲,是只讀的
- name,參數(shù)的名字
- annotation 洛二,參數(shù)的注解馋劈,可能沒有定義
- default,參數(shù)的缺省值晾嘶,可能沒有定義
- empty妓雾,特殊的類,用來標(biāo)記default屬性或者注釋annotation屬性的空值
- kind变擒,實(shí)參如何綁定到形參君珠,就是形參的類型
- POSITIONAL_ONLY ,值必須是位置參數(shù)提供 (Python中沒有)
- POSITIONAL_OR_KEYWORD 娇斑, 值可以作為關(guān)鍵字或者位置參數(shù)提供
- VAR_POSITIONAL 策添, 可變參數(shù)材部,對(duì)應(yīng)*args
- KEYWORD_ONLY ,kwword_only 參數(shù)唯竹,對(duì)應(yīng)*或者args之后的出現(xiàn)的非可變參數(shù)關(guān)鍵字參數(shù)
- VAR_KEYWORD 乐导,可變關(guān)鍵字參數(shù),對(duì)應(yīng)**kwargs
### 檢查用戶輸入是否符合參數(shù)注解的要求
from functools import wraps
import inspect
def check(fn):
@wraps(fn)
def wrapper(*args,**kwargs):
sig = inspect.signature(fn)
params = sig.parameters # 有序字典
# print(params)
values = list(params.values())
# flag = True
for i,p in enumerate(args):
param = values[i]
if param.annotation is not param.empty and not isinstance(p,param.annotation):
print(p,'!==',values[i].annotation)
# flag = False
# break
# if not flag:
# raise TypeError('都是你的錯(cuò)')
for k,v in kwargs.items():
if params[k].annotation is not inspect._empty and isinstance(v,params[k].annotation):
print(k,v,'!==',params[k].annotation)
return fn(*args,**kwargs)
return wrapper
@check
def add(x:int,y:int=6)->int:
return x + y
add(20,30)