摘要:裝飾器基礎本質本質是語法糖使用來修飾某個函數時其解釋器會解釋成注意這條語句會被執行多重裝飾器相當于帶參數裝飾器相當于使用給被裝飾函數傳遞參數是一個數組,一個字典帶參數的裝飾器等同于方法裝飾器類方法是一個特殊的函數,它的第一個參數指向類實例
python decorators 裝飾器基礎 Decorator 本質
@ 本質是語法糖- Syntactic Sugar
使用@decorator 來修飾某個函數 func 時:
@decorator def func(): pass
其解釋器會解釋成:
func = decorator(func)
注意這條語句會被執行
多重裝飾器
@decorator_one @decorator_two def func(): pass
相當于:
func = decorator_one(decorator_two(func))
帶參數裝飾器
@decorator(arg1, arg2) def func(): pass
相當于:
func = decorator(arg1,arg2)(func)使用 *args、**kwargs 給被裝飾函數傳遞參數
def wrapper(func): def wrapper_in(*args, **kwargs): # args是一個數組,kwargs一個字典 print("%s is running" % func.__name__) return func(*args, **kwargs) return wrapper_in @wrapper def func(parameter1, parameter2, key1=1): print("call func with {} {} {}".format(parameter1, parameter2, key1)) func("haha", None, key1=2) # func is running # call func with haha None 2帶參數的裝飾器
def log(level): def decorator(func): def wrapper(*args, **kwargs): if level == "warn": print("%s with warn is running" % func.__name__) elif level == "info": print("%s with info is running" % func.__name__) return func(*args, **kwargs) return wrapper return decorator @log("warn") def foo(*args, **kwargs): print("args {}, kwargs{}".format(args, kwargs)) foo(1, 2, a = 3) # foo with warn is running # args (1, 2), kwargs{"a": 3}
等同于
def foo(name="foo"): print("args {}, kwargs{}".format(args, kwargs)) foo = log("warn")(foo)方法裝飾器
類方法是一個特殊的函數,它的第一個參數 self 指向類實例
所以我們同樣可以裝飾類方法
def decorate(func): def wrapper(self): return "{0}
".format(func(self)) return wrapper class Person(object): def __init__(self): self.name = "John" self.family = "Doe" @decorate def get_fullname(self): return self.name+" "+self.family my_person = Person() print my_person.get_fullname() #John Doe
上例相當于固定了 self 參數,不太靈活
使用 *args, **kwargs傳遞給 wrapper 更加通用:
def pecorate(func): def wrapper(*args, **kwargs): return "類裝飾器{0}
".format(func(*args, **kwargs)) return wrapper class Person(object): def __init__(self): self.name = "John" self.family = "Doe" @pecorate def get_fullname(self): return self.name+" "+self.family my_person = Person() print my_person.get_fullname()
類實現 __call__ 方法后變成可調用對象,故可以用類做裝飾器
class EntryExit(object): def __init__(self, f): self.f = f def __call__(self): print "Entering", self.f.__name__ self.f() print "Exited", self.f.__name__ @EntryExit def func1(): print "inside func1()" @EntryExit def func2(): print "inside func2()" def func3(): pass print type(EntryExit(None)) # func1 變為類實例 print type(func1) print type(EntryExit) # func3 是普通函數 print type(func3) func1() func2() ## # # # Entering func1 # inside func1() # Exited func1 # Entering func2 # inside func2() # Exited func2
類裝飾器
@EntryExit def func1(): print "inside func1()"
等同于
def func1(): print "inside func1()" # 此處可以看出 func1 是類EntryExit的一個實例 func1 = EntryExit(myfunc1)裝飾器裝飾類
register_handles = [] def route(url): global register_handles def register(handler): register_handles.append((".*$", [(url, handler)])) return handler return register @route("/index") class Index(): def get(self, *args, **kwargs): print("hi") # Index 仍然為原來定義的類實例 # 相當于在定義類的同時調用裝飾器函數 route, 將該類注冊到全局路由 register_handles @route("/main") class Main(): def get(self, *args, **kwargs): print("hi") print (register_handles) print(type(Index)) # [(".*$", [("/index",)]), (".*$", [("/main", )])] #
@route("/index") class Index(): def get(self, *args, **kwargs): print("hi")
Index = route("/index")(Index) # register 返回傳入的 handler,故 Index 仍然為類對象functools
上述裝飾器實現有個問題,就是被裝飾函數的屬性被改變
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/42700.html
摘要:裝飾器傳參被裝飾的函數帶有參數的情況接上一篇,直接上代碼函數也就是被裝飾的函數的運行時間是裝飾器的正確使用,不需要傳參裝飾器的正確使用,需要傳參此時不用再像上面一樣賦值,可以直接調用返回值被裝飾的函數有返回值在裝飾器內部需被裝飾函數的調用 python 裝飾器 傳參 被裝飾的函數帶有參數的情況 接上一篇,直接上代碼 import time def decorator(func): ...
一、前提概念 Python中的函數是對象。也因此,函數可以被當做變量使用。 二、代碼模型 以下代碼片段來自于: http://www.sharejs.com/codes/python/8361 # -*- coding: utf-8 -*- from threading import Thread import time class TimeoutEx...
摘要:裝飾器是可調用的對象,其參數是另一個函數被裝飾的函數。第二大特性是,裝飾器在加載模塊時立即執行。另一個常見的裝飾器是,它的作用是協助構建行為良好的裝飾器。 裝飾器是可調用的對象,其參數是另一個函數(被裝飾的函數)。 裝飾器基礎知識 首先看一下這段代碼 def deco(fn): print I am %s! % fn.__name__ @deco def func(): ...
摘要:使用類裝飾器,優點是靈活性大,高內聚,封裝性。不過不用擔心,有,本身也是一個裝飾器,它的作用就是把原函數的元信息拷貝到裝飾器函數中,使得裝飾器函數也有和原函數一樣的元信息。 showImg(https://segmentfault.com/img/bVbrFWb?w=742&h=484);Python的裝飾器(decorator)是一個很棒的機制,也是熟練運用Python的必殺技之一。...
摘要:為了避免重復調用,可以適當地做緩存,的裝飾器可以完美的完成這一任務。這意味著我們可以為方法創建裝飾器,只是要記得考慮。裝飾器封裝了函數,這使得調試函數變得困難。另外,使用裝飾器去管理緩存和權限。 原文地址 之前用python簡單寫了一下斐波那契數列的遞歸實現(如下),發現運行速度很慢。 def fib_direct(n): assert n > 0, invalid n ...
閱讀 1771·2021-11-25 09:43
閱讀 15327·2021-09-22 15:11
閱讀 2623·2019-08-30 13:19
閱讀 2009·2019-08-30 12:54
閱讀 1815·2019-08-29 13:06
閱讀 923·2019-08-26 14:07
閱讀 1612·2019-08-26 10:47
閱讀 3028·2019-08-26 10:41