python 裝飾器重要在哪

2022-09-29 17:48:17 字數 4218 閱讀 3322

要理解什麼是裝飾器,您首先需要熟悉python處理函式的方式。從它的觀點來看,函式和物件沒有什麼不同。它們有屬性,可以重新分配:

def func():

print('hello from func')

func()

> hello from func

new_func = func

new_func()

> hello from func

print(new_func.__name__)

> func

此外,你還可以將它們作為引數傳遞給其他函式:

def func():

print('hello from func')

def call_func_twice(callback):

callback()

callback()

call_func_twice(func)

> hello from func

> hello from func

現在,我們介紹裝飾器。裝飾器(decorator)用於修改函式或類的行為。實現這一點的方法是定義乙個返回另乙個函式的函式(裝飾器)。這聽起來很複雜,但是通過這個例子你會理解所有的東西:

def logging_decorator(func):

def logging_wrapper(*args, **kwargs):

print(f'before ')

func(*args, **kwargs)

print(f'after ')

return logging_wrapper

@logging_decorator

def sum(x, y):

print(x + y)

sum(2, 5)

> before sum

> 7

> after sum

讓我們一步一步來:

這很簡單:可讀性。python因其清晰簡潔的語法而備受讚譽,裝飾器也不例外。如果有任何行為是多個函式共有的,那麼您可能需要製作乙個裝飾器。下面是一些可能會派上用場的例子:

和更多…

現在我們將列出一些**示例。

帶有返回值的裝飾器

假設我們想知道每個函式呼叫需要多長時間。而且,函式大多數時候都會返回一些東西,所以裝飾器也必須處理它:

def timer_decorator(func):

def timergkdhe_wrapper(*args, **kwargs):

import datetime

before = datetime.datetime.now()

result = func(*args,**kwargs)

after = datetime.datetime.now()

print "elapsed time = ".format(after-before)

return result

@timer_decorator

def sum(x, y):

print(x + y)

return x + y

sum(2, 5)

> 7

> elapsed time = some time

可以看到,我們將返回值儲存在第5行的result中。但在返回之前,我們必須完成對函式的計時。這是乙個沒有裝飾者就不可能實現的行為例子。

帶有引數的裝飾器

有時候,我們想要乙個接受值的裝飾器(比如flask中的@app.route('/login'):

def permission_decorator(permission):

def _permission_decorator(func):

def permission_wrapper(*args, **kwargs):

if someuserapi.haspermission(permission):

result = func(*args, **kwargs)

return result

return none

return permission wrapper

return _permission_decorator

@permission_decorator('admin')

def delete_user(user):

someuserapi.deleteuser(user)

為了實現這一點,我們定義了乙個額外的函式,它接受乙個引數並返回乙個裝飾器。

帶有類的裝飾器

使用類代替函式來修飾是可能的。唯一的區別是語法,所以請使用您更熟悉的語法。下面是使用類重寫的日誌裝飾器:

class logging:

def __init__(self, function):

self.function = function

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

print(f'before ')

self.程式設計客棧function(*args, **kwargs)

print(f'after ')

@logging

def sum(x, y):

print(x + y)

sum(5, 2)

> before sum

> 7

> after sum

這樣做的好處是,您不必處理巢狀函式。你所需要做的就是定義乙個類並覆蓋__call__方法。

裝飾類有時,您可能想要修飾類中的每個方法。你可以這樣寫

class myclass:

@decorator

def func1(self):

pass

@decorator

def func2(self):

pass

但如果你有很多方法,這可能會失控。值得慶幸的是,有一種方法可以一次性裝飾整個班級:

def logging_decorator(func):

def logging_wrapper(*args, **kwargs):

print(f'before ')

result = func(*args, **kwargs)

print(f'after ')

return result

return logging_wrapper

def log_all_class_methods(cls):

class newcls(object):

def __init__(self, *args, **kwarggkdhes):

self.original = cls(*args, **kwargs)

def __getattribute__(self, s):

try:

x = super(newcls,self).__getattribute__(s)

except attributeerror:

pass

else:

return x

x = self.original.__getattribute__(s)

if type(x) == type(self.__init__):

return logging_decorator(x)

else:

return x

return newcls

@log_all_class_methods

class somemethods:

def func1(self):

print('func1')

def func2(self):

print('func2')

methods = somemethods()

methods.func1()

> before func1

> func1

> after func1

現在,不要驚慌。這看起來很複雜,但邏輯是一樣的:

內建的修飾符

您不僅可以定義自己的decorator,而且在標準庫中也提供了一些decorator。我將列出與我一起工作最多的三個人:

@property -乙個內建外掛程式的裝飾器,它允許你為類屬性定義getter和setter。

@lru_cache - functools模組的裝飾器。它記憶函式引數和返回值,這對於純函式(如階乘)很方便。

@abstractmethod——abc模組的裝飾器。指示該方法是抽象的,且缺少實現細節。

python學習記錄 裝飾器(重點)

裝飾器不是乙個新的概念,而是空間名稱,閉包函式等等的組合就是裝飾器 裝飾 給函式增加額外的功能 器 就是工具 裝飾器的核心思想 在不改變原有函式的 情況和原有呼叫方式的基礎上增加額外的功能 def index pass index 給index函式統計執行時間 儲備知識 time模組 import ...

python函式裝飾器,重點必須掌握(二)

繼續說 4.未知型別,未知個數引數 args 可以表示整型,浮點型,字串,列表,元組等引數。例子 def func 1 args print args print args func 1 1,4.44444 abc 1,扒點剛貨 2,badianganghuo 執行結果 1,4.44444 abc ...

學習記錄 構造器(重要)

alt insert constructor 快速建立構造器 例項化物件student student student new student 這個過程就是呼叫建構函式。類裡面會存在乙個隱藏的無參構造器 子類會隱藏呼叫父類的構造器 隱藏 呼叫了父類的無參構造必須在第一行 super 呼叫父類的構造器...