Python 裝飾器(decorator)總結

2021-10-09 00:08:41 字數 2115 閱讀 9944

最近總體研究了一下python的裝飾器,在這裡做一下總結

普通裝飾器基本如下,使用起來簡單方便,下面這個是最簡單的例子,呼叫方法前列印一下方法的名字

def decorator(func):

print func.__name__

func()

@decorator

def func():

do something

func = decorator(func)
上面提到的普通裝飾器,裝飾的是沒有引數的函式,下面這個展示的是如果寫乙個帶有引數的函式的裝飾器,其實也很簡單

def decorator(func):

print func.__name__

func(*args, **kwars)

@decorator

def func(something):

print something

裝飾器本身帶引數個人認為是很常見的用法,可以對裝飾器本身做一些控制,從**看跟無引數裝飾器最直觀的區別就是要多包一層

def decorator(arg):

print args

print func.__name__

func(*args, **kwargs)

@decorator(arg=arg)

def func(something):

print something

類作為裝飾器這個平時用的不多,這個用法還是很神奇的,主要是要用到__call__方法

class decorator(object):  # python3 中就不需要顯式的繼承object了

def __init__(self, func):

self.func = func

def __call__(self, *args, **kwargs):

print self.func.__name__

func(*args, **kwargs)

@decorator

def func(something):

print something

跟普通裝飾器其實是一樣的,呼叫decorator裝飾的方法func相當於是 

decorator(func).__call__()
有了上面這幾個裝飾器做基礎,這個理解起來也不難

class decorator(object):

def __init__(self, arg):

self.arg = arg

def __call__(self, func):

print func.__name__

func(*args, **kwargs)

@decorator(arg=arg)

def func(something):

print something

1. 錯誤的函式簽名和文件

裝飾器裝飾過的函式看上去名字沒變,其實已經變了,包括doc。使用標準庫里的functools.warps基本可以解決這個問題

def decorator(func):

@warps(func)

def warpper(*args, **kwargs):

return func(*args, **kwargs)

2. 不能用來裝飾@classmethod 和 @staticmethod

因為@staticmethon和@classmethod返回的並不是乙個callable物件,而是乙個staticmethod的物件,這不符合裝飾器的定義。解決方案是把裝飾器放在@classmethod和@staticmethod之前。注意這裡說的之前不是寫在前一行,而是後一行,因為裝飾器是從離函式最近的這個開始起作用的

@classmethod

@decorator

def func():

do_something

Python基礎知識之裝飾器decorator

本質是函式,裝飾其他函式 為其他函式新增附加功能。不能修改被裝飾的函式的源 不能修改被裝飾的函式的呼叫方式 高階函式 巢狀函式 裝飾器 1.函式即 變數 定義乙個函式就相當於定義乙個變數,即將函式體賦值給乙個變數名。python的記憶體 機制規定 當儲存在記憶體中的內容沒有對應的變數名指定時,則當記...

python裝飾器 Python 裝飾器

簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 這是我們最原始的的乙個函式,然後我們試圖記錄...

python裝飾器 裝飾器

由於函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式。def now print 2015 3 25 f now f 2015 3 25 函式物件有乙個 name 屬性,可以拿到函式的名字 now.name now f.name now 現在,假設我們要增強now 函式的...