python 高階函數(shù)

高階函數(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] ) )

柯里化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)
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末浸颓,一起剝皮案震驚了整個(gè)濱河市物臂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌产上,老刑警劉巖棵磷,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異晋涣,居然都是意外死亡仪媒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門谢鹊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來算吩,“玉大人,你說我怎么就攤上這事佃扼≠顺玻” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵兼耀,是天一觀的道長(zhǎng)压昼。 經(jīng)常有香客問我,道長(zhǎng)瘤运,這世上最難降的妖魔是什么巢音? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮尽超,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梧躺。我一直安慰自己似谁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布掠哥。 她就那樣靜靜地躺著巩踏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪续搀。 梳的紋絲不亂的頭發(fā)上塞琼,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音禁舷,去河邊找鬼彪杉。 笑死毅往,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的派近。 我是一名探鬼主播攀唯,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼渴丸!你這毒婦竟也來了侯嘀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤谱轨,失蹤者是張志新(化名)和其女友劉穎戒幔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體土童,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诗茎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了娜扇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片错沃。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖雀瓢,靈堂內(nèi)的尸體忽然破棺而出枢析,到底是詐尸還是另有隱情,我是刑警寧澤刃麸,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布醒叁,位于F島的核電站,受9級(jí)特大地震影響泊业,放射性物質(zhì)發(fā)生泄漏把沼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一吁伺、第九天 我趴在偏房一處隱蔽的房頂上張望饮睬。 院中可真熱鬧,春花似錦篮奄、人聲如沸捆愁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昼丑。三九已至,卻和暖如春夸赫,著一層夾襖步出監(jiān)牢的瞬間菩帝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呼奢,地道東北人宜雀。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像控妻,于是被迫代替她去往敵國(guó)和親州袒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355