亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

Python裝飾器探究——裝飾器參數(shù)

macg0406 / 500人閱讀

摘要:示例中我們編寫(xiě)的裝飾器只接受一個(gè)隱式參數(shù)即被裝飾的方法,在使用此裝飾器時(shí)本身看上去是并沒(méi)有參數(shù)的。實(shí)際上裝飾器里的后接收一個(gè)函數(shù),該函數(shù)以被裝飾的函數(shù)例子中是為參數(shù),并且返回一個(gè)函數(shù)。

探究裝飾器參數(shù) 編寫(xiě)傳參的裝飾器

通常我們見(jiàn)到的簡(jiǎn)單裝飾器這樣的:

import json
import functools

def json_output(func):
    @functools.wraps(decorated)
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        return json.dumps(result)
    return inner

@json_output
def f():
    return {"status": "done"}

當(dāng)裝飾器應(yīng)用于函數(shù) f 上時(shí),它接受 f 作為其參數(shù),返回一個(gè)函數(shù) inner ,且將他綁定到變量f上。

示例中我們編寫(xiě)的裝飾器 json_output 只接受一個(gè)隱式參數(shù)——即被裝飾的方法,在使用此裝飾器時(shí)本身看上去是并沒(méi)有參數(shù)的。然而有時(shí)候需要讓裝飾器自身帶有一些需要的信息,從而使裝飾器可以使用恰當(dāng)?shù)姆绞窖b飾方法。比如上面的例子中,我們想通過(guò)向裝飾器傳入不同的參數(shù)來(lái)控制輸出結(jié)果的縮進(jìn)(indent)和排序(sort)。我們可以這么做:

import json
import functools

def json_output(indent=None, sort_keys=False):
    def actual_decorator(func):
        @functools.wraps(func)
        def inner(*args, **kwargs):
            result = func(*args, **kwargs)
            return json.dumps(result, indent=indent, sort_keys=sort_keys)
        return inner
    return actual_decorator

@json_output(indent=4)
def f():
    return {"status": "done"}
理解傳參的裝飾器

初次看起來(lái)會(huì)覺(jué)得比較繞人,因?yàn)楹瘮?shù)里嵌套了兩個(gè)函數(shù)定義,然而實(shí)際上和之前一個(gè)版本的區(qū)別在于為了接收json序列化的參數(shù)多包裝了一層,所以

@json_output(indent=4)
def f():
    return {"status": "done"}

# 相當(dāng)于
@actual_decorator
def f():
    return {"status": "done"}

這樣看起來(lái)就會(huì)明晰很多。

實(shí)際上, 裝飾器里的 @ 后接收一個(gè)函數(shù),該函數(shù)以被裝飾的函數(shù)(例子中是f)為參數(shù),并且返回一個(gè)函數(shù)。當(dāng)需要在裝飾函數(shù)的同時(shí)傳入?yún)?shù)的話(huà),那么就需要多包裝一層,先傳入?yún)?shù)(例子中是 indent=4 )返回一個(gè)裝飾的函數(shù)(例子中是 actual_decorator ), 這個(gè)返回的的函數(shù) 就跟以前一樣接受被裝飾的函數(shù)(f)作為參數(shù)并且返回一個(gè)函數(shù)作為裝飾最后的方法供調(diào)用。

傳參和不傳參的兼容

然而當(dāng)我們像上面那樣定義裝飾器時(shí),就不能這樣調(diào)用:

import json
import functools

def json_output(indent=None, sort_keys=False):
    def actual_decorator(func):
        @functools.wraps(func)
        def inner(*args, **kwargs):
            result = func(*args, **kwargs)
            return json.dumps(result, indent=indent, sort_keys=sort_keys)
        return inner
    return actual_decorator

@json_output
def f():
    return {"status": "done"}

在實(shí)際的項(xiàng)目過(guò)程中,有時(shí)會(huì)出現(xiàn)這樣的狀況: 一開(kāi)始寫(xiě)的裝飾器時(shí)不需要使用時(shí)傳參數(shù)的,后來(lái)發(fā)現(xiàn)有必要傳參數(shù),改好后原來(lái)不傳參的裝飾器不能正常使用了,這是修改原來(lái)使用的地方是項(xiàng)痛苦的事情。
這時(shí)候就需要對(duì)裝飾器做一個(gè)兼容,使它在以下情況都可用:

@json_output
@json_output()
@json_output(indent=4)

具體做法如下:

import json
import functools

def json_output(decorated_=None, indent=None, sort_keys=False):
    if decorated_ and (indent or sort_keys):
        raise

    def actual_decorator(func):
        @functools.wraps(func)
        def inner(*args, **kwargs):
            result = func(*args, **kwargs)
            return json.dumps(result, indent=indent, sort_keys=sort_keys)
        return inner
    if decorated_:
        return actual_decorator(decorated_)
    else:
        return actual_decorator


@json_output(indent=4)
def f1():
    return {"status": "done"}

@json_output
def f2():
    return {"status": "done"}

@json_output()
def f3():
    return {"status": "done"}

print f1()
print f2()
print f3()

代碼中關(guān)鍵的地方在于 json_output 在最后對(duì)參數(shù) decorated 進(jìn)行了判斷,有的話(huà)證明是不傳參調(diào)用,那么直接返回 actual_decorator 的調(diào)用;沒(méi)有的話(huà)則代表是傳參類(lèi)型的調(diào)用(雖然參數(shù)可能不存在),那么返回 actual_decorator 。其中有點(diǎn)需要注意, josn_output 的傳參需要使用關(guān)鍵字參數(shù),如果像下面這樣直接傳一個(gè)位置參數(shù),那么根據(jù)現(xiàn)在的實(shí)現(xiàn)會(huì)出現(xiàn)錯(cuò)誤(因?yàn)樗鼤?huì)被當(dāng)成 decorated_ )。

@json_output(4)  #錯(cuò)誤的使用方法
def f4():
    return {"status": "done"}
參考資料

《Python高級(jí)編程》 by Luke Sneeriger

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/38291.html

相關(guān)文章

  • Python 裝飾執(zhí)行順序迷思

    摘要:探究多個(gè)裝飾器執(zhí)行順序裝飾器是用于封裝函數(shù)或代碼的工具,網(wǎng)上可以搜到很多文章可以學(xué)習(xí),我在這里要討論的是多個(gè)裝飾器執(zhí)行順序的一個(gè)迷思。這時(shí)候你該知道為什么輸出結(jié)果會(huì)是那樣,以及對(duì)裝飾器執(zhí)行順序?qū)嶋H發(fā)生了什么有一定了解了吧。 探究多個(gè)裝飾器執(zhí)行順序 裝飾器是Python用于封裝函數(shù)或代碼的工具,網(wǎng)上可以搜到很多文章可以學(xué)習(xí),我在這里要討論的是多個(gè)裝飾器執(zhí)行順序的一個(gè)迷思。 疑問(wèn) 大部...

    frolc 評(píng)論0 收藏0
  • Python裝飾-裝飾流程,執(zhí)行順序

    摘要:最近看到一個(gè)關(guān)于的題文章其中的一個(gè)是裝飾器的順序問(wèn)題就想寫(xiě)篇博客回顧下裝飾器首先強(qiáng)烈推薦很久之前看的一篇博文翻譯理解中的裝飾器關(guān)于什么是裝飾器看這篇文章就好了這里主要想寫(xiě)關(guān)于多個(gè)裝飾器的執(zhí)行流程裝飾順序示例代碼初始化初始化輸出結(jié)果初始化初始 最近看到一個(gè)關(guān)于Flask的CTF(RealWorld CTF 2018 web題bookhub)文章其中的一個(gè)trick是裝飾器的順序問(wèn)題,就想...

    cpupro 評(píng)論0 收藏0
  • Python】一文弄懂python裝飾(附源碼例子)

    摘要:裝飾器的使用符合了面向?qū)ο缶幊痰拈_(kāi)放封閉原則。三簡(jiǎn)單的裝飾器基于上面的函數(shù)執(zhí)行時(shí)間的需求,我們就手寫(xiě)一個(gè)簡(jiǎn)單的裝飾器進(jìn)行實(shí)現(xiàn)。函數(shù)體就是要實(shí)現(xiàn)裝飾器的內(nèi)容。類(lèi)裝飾器的實(shí)現(xiàn)是調(diào)用了類(lèi)里面的函數(shù)。類(lèi)裝飾器的寫(xiě)法比我們裝飾器函數(shù)的寫(xiě)法更加簡(jiǎn)單。 目錄 前言 一、什么是裝飾器 二、為什么要用裝飾器 ...

    liuchengxu 評(píng)論0 收藏0
  • Python: 會(huì)打扮的裝飾

    摘要:一般情況下,我們使用裝飾器提供的語(yǔ)法糖,來(lái)簡(jiǎn)化上面的寫(xiě)法像上面的情況,可以動(dòng)態(tài)修改函數(shù)或類(lèi)功能的函數(shù)就是裝飾器。本文標(biāo)題為會(huì)打扮的裝飾器本文鏈接為參考資料修飾器的函數(shù)式編程中的裝飾器介紹思誠(chéng)之道裝飾器入門(mén)與提高賴(lài)明星 裝飾器 我們知道,在 Python 中,我們可以像使用變量一樣使用函數(shù): 函數(shù)可以被賦值給其他變量 函數(shù)可以被刪除 可以在函數(shù)里面再定義函數(shù) 函數(shù)可以作為參數(shù)傳遞給另外...

    blastz 評(píng)論0 收藏0
  • Python學(xué)習(xí)之路26-函數(shù)裝飾和閉包

    摘要:初步認(rèn)識(shí)裝飾器函數(shù)裝飾器用于在源代碼中標(biāo)記函數(shù),以某種方式增強(qiáng)函數(shù)的行為。函數(shù)裝飾器在導(dǎo)入模塊時(shí)立即執(zhí)行,而被裝飾的函數(shù)只在明確調(diào)用時(shí)運(yùn)行。只有涉及嵌套函數(shù)時(shí)才有閉包問(wèn)題。如果想保留函數(shù)原本的屬性,可以使用標(biāo)準(zhǔn)庫(kù)中的裝飾器。 《流暢的Python》筆記本篇將從最簡(jiǎn)單的裝飾器開(kāi)始,逐漸深入到閉包的概念,然后實(shí)現(xiàn)參數(shù)化裝飾器,最后介紹標(biāo)準(zhǔn)庫(kù)中常用的裝飾器。 1. 初步認(rèn)識(shí)裝飾器 函數(shù)裝飾...

    sunny5541 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<