python 高階篇 函式裝飾器和類裝飾器

2022-03-27 20:32:47 字數 2295 閱讀 4240

簡單裝飾器

def my_decorator(func):

func()

def greet():

print('hello world')

greet = my_decorator(greet)

greet()

# 輸出

# hello world

上述**在 python 中有更簡單、更優雅的表示:

def my_decorator(func):

func()

@my_decorator

def greet():

print('hello world')

greet()

# 輸出

# hello world

帶引數的裝飾器

def my_decorator(func):

func(*args, **kwargs)

@my_decorator

def greet(message):

print(message)

greet('hello world')

# 輸出

# hello world

自定義引數的裝飾器

def repeat(num):

def my_decorator(func):

for i in range(num):

func(*args, **kwargs)

return my_decorator

@repeat(4)

def greet(message):

print(message)

greet('hello world')

# 輸出:

# hello world

# hello world

# hello world

# hello world

原函式還是原函式嗎?

試著列印出 greet() 函式的一些元資訊:

greet.__name__

## 輸出

help(greet)

# 輸出

為了解決這個問題,通常使用內建的裝飾器@functools.wrap,它會幫助保留原函式的元資訊(也就是將原函式的元資訊,拷貝到對應的裝飾器函式裡)。

import functools

def my_decorator(func):

@functools.wraps(func)

func(*args, **kwargs)

@my_decorator

def greet(message):

print(message)

greet.__name__

# 輸出

'greet'

實際上,類也可以作為裝飾器。類裝飾器主要依賴於函式__call__(),每當你呼叫乙個類的示例時,函式__call__()就會被執行一次。

class count:

def __init__(self, func):

self.func = func

self.num_calls = 0

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

self.num_calls += 1

print('num of calls is: {}'.format(self.num_calls))

return self.func(*args, **kwargs)

@count

def example():

print("hello world")

example()

# 輸出

num of calls is: 1

hello world

example()

# 輸出

num of calls is: 2

hello world

我們定義了類 count,初始化時傳入原函式func(),而__call__()函式表示讓變數 num_calls 自增 1,然後列印,並且呼叫原函式。因此,在我們第一次呼叫函式example()時,num_calls 的值是 1,而在第二次呼叫時,它的值變成了 2

PYTHON高階函式和裝飾器

定義 裝飾器的本質是函式,用來裝飾其他的函式,為其他的函式新增功能。函式修飾符 用做函式的修飾符,可以在模組或者類的定義層內對函式進行修飾,出現在函式定義的前一行,不允許和函式定義在同一行乙個修飾符就是乙個函式,它將被修飾的函式作為引數,並返回修飾後的同名函式或其他可呼叫的東西 原則 1 不能修改被...

Python高階函式 裝飾器

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

Python 高階函式 裝飾器

裝飾器 定義裝飾器本身是乙個可呼叫物件,接收乙個函式作為引數,然後將其返回或替換成另乙個函式或可呼叫物件。可以理解成,原來那是一堵白牆,經過了一層裝飾,這層裝飾可能是漆也可能把牆掏空鑲進一層 變得金光閃閃,最後呈現在你眼前的就是裝飾後的樣子。可以把它完全當成常規函式來呼叫,其引數是另乙個函式。裝飾器...