<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        Python修飾器與functools_html/css

        來源:懂視網 責編:小采 時間:2020-11-27 16:22:19
        文檔

        Python修飾器與functools_html/css

        Python修飾器與functools_html/css_WEB-ITnose:Python 的修飾器是一種語法糖(Syntactic Sugar),也就是說: @decorator@wrapdef func(): pass 是下面語法的一種簡寫: def func(): passfunc = decorator(wrap(func)) 關于修飾器的兩個主要問題: 修飾器用來修飾誰 誰可以作為修飾器
        推薦度:
        導讀Python修飾器與functools_html/css_WEB-ITnose:Python 的修飾器是一種語法糖(Syntactic Sugar),也就是說: @decorator@wrapdef func(): pass 是下面語法的一種簡寫: def func(): passfunc = decorator(wrap(func)) 關于修飾器的兩個主要問題: 修飾器用來修飾誰 誰可以作為修飾器

        Python 的修飾器是一種語法糖(Syntactic Sugar),也就是說:

        @decorator@wrapdef func(): pass

        是下面語法的一種簡寫:

        def func(): passfunc = decorator(wrap(func))

        關于修飾器的兩個主要問題:

        1. 修飾器用來修飾誰

        2. 誰可以作為修飾器

        修飾函數

        修飾器最常見的用法是修飾新定義的函數,在 0x0d 上下文管理器中提到上下文管理器主要是為了 更優雅地完成善后工作,而修飾器通常用于擴展函數的行為或屬性:

        def log(func): def wraper(): print("INFO: Starting {}".format(func.__name__)) func() print("INFO: Finishing {}".format(func.__name__)) return wraper@logdef run(): print("Running run...")run()
        INFO: Starting runRunning run...INFO: Finishing run

        修飾類

        除了修飾函數之外,Python 3.0 之后增加了對新定義類的修飾(PEP 3129),但是對于類別屬性的修改可以通過 Metaclasses或繼承來實現,而新增加的類別修飾器更多是出于 Jython 以及 IronPython 的考慮,但其語法還是很一致的:

        from time import sleep, timedef timer(Cls): def wraper(): s = time() obj = Cls() e = time() print("Cost {:.3f}s to init.".format(e - s)) return obj return wraper@timerclass Obj: def __init__(self): print("Hello") sleep(3) print("Obj")o = Obj()
        HelloObjCost 3.005s to init.

        類作為修飾器

        上面兩個例子都是以函數作為修飾器,因為函數才可以被調用(callable) decorator(wrap(func))。除了函數之外,我們也可以定義可被調用的類,只要添加 __call__方法即可:

        class HTML(object): """ Baking HTML Tags! """ def __init__(self, tag="p"): print("LOG: Baking Tag <{}>!".format(tag)) self.tag = tag def __call__(self, func): return lambda: "<{0}>{1}".format(self.tag, func(), self.tag) @HTML("html")@HTML("body")@HTML("div")def body(): return "Hello"print(body())
        LOG: Baking Tag !LOG: Baking Tag !LOG: Baking Tag !Hello

        傳遞參數

        在實際使用過程中,我們可能需要向修飾器傳遞參數,也有可能需要向被修飾的函數(或類)傳遞參數。按照語法約定,只要修飾器 @decorator中的 decorator是可調用即可, decorator(123)如果返回一個新的可調用函數,那么也是合理的,上面的 @HTML('html')即是一例,下面再以 flask 的路由修飾器為例說明如何傳遞參數給修飾器:

        RULES = {}def route(rule): def decorator(hand): RULES.update({rule: hand}) return hand return decorator @route("/")def index(): print("Hello world!")def home(): print("Welcome Home!")home = route("/home")(home)index()home()print(RULES)
        Hello world!Welcome Home!{'/': , '/home': }

        向被修飾的函數傳遞參數,要看我們的修飾器是如何作用的,如果像上面這個例子一樣未執行被修飾函數只是將其原模原樣地返回,則不需要任何處理(這就把函數當做普通的值一樣看待即可):

        @route("/login")def login(user = "user", pwd = "pwd"): print("DB.findOne({{{}, {}}})".format(user, pwd))login("hail", "python")
        DB.findOne({hail, python})

        如果需要在修飾器內執行,則需要稍微變動一下:

        def log(f): def wraper(*args, **kargs): print("INFO: Start Logging") f(*args, **kargs) print("INFO: Finish Logging") return wraper@logdef run(hello = "world"): print("Hello {}".format(hello))run("Python")
        INFO: Start LoggingHello PythonINFO: Finish Logging

        functools

        由于修飾器將函數(或類)進行包裝之后重新返回: func = decorator(func),那么有可能改變原本函數(或類)的一些信息,以上面的 HTML修飾器為例:

        @HTML("body")def body(): """ return body content """ return "Hello, body!"print(body.__name__)print(body.__doc__)
        LOG: Baking Tag !None

        因為 body = HTML("body")(body),而 HTML("body").__call__()返回的是一個 lambda函數,因此 body已經被替換成了 lambda,雖然都是可執行的函數,但原來定義的 body中的一些屬性,例如 __doc__/ __name__/ __module__都被替換了(在本例中 __module__沒變因為都在同一個文件中)。為了解決這一問題 Python 提供了 functools標準庫,其中包括了 update_wrapper和 wraps兩個方法(源碼)。其中 update_wrapper就是用來將原來函數的信息賦值給修飾器中返回的函數:

        from functools import update_wrapper"""functools.update_wrapper(wrapper, wrapped[, assigned][, updated])"""class HTML(object): """ Baking HTML Tags! """ def __init__(self, tag="p"): print("LOG: Baking Tag <{}>!".format(tag)) self.tag = tag def __call__(self, func): wraper = lambda: "<{0}>{1}".format(self.tag, func(), self.tag) update_wrapper(wraper, func) return wraper @HTML("body")def body(): """ return body content! """ return "Hello, body!"print(body.__name__)print(body.__doc__)
        LOG: Baking Tag !body return body content!

        有趣的是 update_wrapper的用法本身就很像是修飾器,因此 functools.wraps就利用 functools.partial(還記得函數式編程中的偏應用吧!)將其變成一個修飾器:

        from functools import update_wrapper, partialdef my_wraps(wrapped): return partial(update_wrapper, wrapped=wrapped)def log(func): @my_wraps(func) def wraper(): print("INFO: Starting {}".format(func.__name__)) func() print("INFO: Finishing {}".format(func.__name__)) return wraper@logdef run(): """ Docs' of run """ print("Running run...")print(run.__name__)print(run.__doc__)
        run Docs' of run

        參考

        1. Python修飾器的函數式編程

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Python修飾器與functools_html/css

        Python修飾器與functools_html/css_WEB-ITnose:Python 的修飾器是一種語法糖(Syntactic Sugar),也就是說: @decorator@wrapdef func(): pass 是下面語法的一種簡寫: def func(): passfunc = decorator(wrap(func)) 關于修飾器的兩個主要問題: 修飾器用來修飾誰 誰可以作為修飾器
        推薦度:
        標簽: html python css
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲五月六月丁香激情| 国产亚洲一区二区精品| 亚洲色少妇熟女11p| 亚洲视频免费一区| 亚洲国产美女精品久久久久| 亚洲成人免费网址| 久久亚洲熟女cc98cm| 最近高清中文字幕无吗免费看| 亚洲视频中文字幕| aa级一级天堂片免费观看| tom影院亚洲国产一区二区| 2021国产精品成人免费视频| 亚洲卡一卡二卡乱码新区| 最近中文字幕mv手机免费高清| 亚洲国产成人久久一区二区三区| 夫妻免费无码V看片| 美女扒开屁股让男人桶爽免费| 亚洲国产成人久久一区久久| 国产在线国偷精品免费看| 久久久久亚洲AV片无码| 国产大片91精品免费观看不卡| 国产 亚洲 中文在线 字幕| 国产免费69成人精品视频| 人体大胆做受免费视频| 亚洲AV无码成人专区片在线观看| 免费视频爱爱太爽了| 男女猛烈xx00免费视频试看| 亚洲午夜福利在线观看| 综合在线免费视频| 一级毛片在播放免费| 亚洲精品影院久久久久久| 午夜免费福利影院| 久久国产精品成人免费| 在线观看亚洲AV每日更新无码| 亚洲男人天堂2020| 国产h肉在线视频免费观看| 国产成人亚洲毛片| 亚洲午夜精品久久久久久人妖| 啦啦啦手机完整免费高清观看| 视频免费在线观看| 亚洲日韩一区二区一无码|