中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么創建和使用Python裝飾器

發布時間:2022-01-26 09:19:38 來源:億速云 閱讀:123 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“怎么創建和使用Python裝飾器”,內容詳細,步驟清晰,細節處理妥當,希望這篇“怎么創建和使用Python裝飾器”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

何時在 Python 中使用裝飾器

當您需要更改函數的行為而不修改函數本身時,您將使用裝飾器。一些很好的例子是當您想要添加日志記錄、測試性能、執行緩存、驗證權限等時。

當您需要在多個函數上運行相同的代碼時,您也可以使用裝飾器。這可以避免您編寫重復的代碼。

以下是用于創建 Python 裝飾器的構建塊

為了更好地理解裝飾器的工作原理,您應該先了解一些概念。

  1. 函數是一個對象。因此,可以將函數分配給變量。可以從該變量訪問該函數。

def my_function():

    print('I am a function.')

# Assign the function to a variable without parenthesis. We don't want to execute the function.

description = my_function
# Accessing the function from the variable I assigned it to.

print(description())

# Output

'I am a function.'

2. 一個函數可以嵌套在另一個函數中。

def outer_function():

    def inner_function():

        print('I came from the inner function.')

    # Executing the inner function inside the outer function.
    inner_function()
outer_function()

# Output

I came from the inner function.

請注意,inner_function在outer_function內部. 如果我嘗試執行inner_function外部,outer_function我會收到 NameError 異常。

inner_function()

Traceback (most recent call last):
  File "/tmp/my_script.py", line 9, in <module>
    inner_function()
NameError: name 'inner_function' is not defined

3. 由于一個函數可以嵌套在另一個函數中,所以它也可以被返回。

def outer_function():
    '''Assign task to student'''

    task = 'Read Python book chapter 3.'
    def inner_function():
        print(task)
    return inner_function

homework = outer_function()
homework()

# Output

'Read Python book chapter 5.'

4. 一個函數可以作為參數傳遞給另一個函數。

def friendly_reminder(func):
    '''Reminder for husband'''

    func()
    print('Don\'t forget to bring your wallet!')

def action():

    print('I am going to the store buy you something nice.')
# Calling the friendly_reminder function with the action function used as an argument.

friendly_reminder(action)

# Output

I am going to the store buy you something nice.
Don't forget to bring your wallet!

如何創建 Python 裝飾器

為了在 Python 中創建裝飾器函數,我創建了一個將函數作為參數的外部函數。還有一個內部函數環繞裝飾函數。

以下是基本 Python 裝飾器的語法:

def my_decorator_func(func):

    def wrapper_func():
        # Do something before the function.
        func()
        # Do something after the function.
    return wrapper_func

要使用裝飾器,您可以將其附加到一個函數,就像您在下面的代碼中看到的那樣。我們通過將裝飾器的名稱直接放在我們想要使用它的函數上方來使用裝飾器。你用一個@符號作為裝飾器函數的前綴。

@my_decorator_func
def my_func():

    pass

這是一個簡單的例子。此裝飾器記錄執行函數的日期和時間:

from datetime import datetime


def log_datetime(func):
    '''Log the date and time of a function'''

    def wrapper():
        print(f'Function: {func.__name__}\nRun on: {datetime.today().strftime("%Y-%m-%d %H:%M:%S")}')
        print(f'{"-"*30}')
        func()
    return wrapper


@log_datetime
def daily_backup():

    print('Daily backup job has finished.')   

     
daily_backup()

# Output

Daily backup job has finished.
Function: daily_backup
Run on: 2021-06-06 06:54:14
---------------------------

如何在 Python 中為裝飾器添加參數

裝飾器可以將參數傳遞給它們。要向裝飾器添加參數,我將*args 和 **kwargs添加到內部函數。

  • *args采取的任何類型的參數,數據類型不受限制,比如10,True,或'Brandon'。

  • **kwargs采取任何類型的關鍵字參數,例如count=99, is_authenticated=True, 或name='Brandon'。

這是一個帶參數的裝飾器:

def my_decorator_func(func):

    def wrapper_func(*args, **kwargs):
        # Do something before the function.
        func(*args, **kwargs)
        # Do something after the function.
    return wrapper_func


@my_decorator_func
def my_func(my_arg):
    '''Example docstring for function'''

    pass

裝飾者隱藏他們正在裝飾的函數。如果我檢查__name__or__doc__方法,我們會得到一個意想不到的結果。

print(my_func.__name__)
print(my_func.__doc__)

# Output

wrapper_func
None

為了解決這個問題,我將使用functools. Functools 包裝將使用裝飾函數屬性更新裝飾器。

from functools import wraps

def my_decorator_func(func):

    @wraps(func)
    def wrapper_func(*args, **kwargs):
        func(*args, **kwargs)
    return wrapper_func

@my_decorator_func
def my_func(my_args):
    '''Example docstring for function'''

    pass

現在我收到了我期待的輸出。

print(my_func.__name__)
print(my_func.__doc__)

# Output

my_func
Example docstring for function

運行中的 Python 裝飾器示例

我創建了一個裝飾器來測量函數的內存和速度。我們將使用裝飾器通過四種方法測試性能列表生成:范圍、列表理解、追加和連接。

from functools import wraps
import tracemalloc
from time import perf_counter 


def measure_performance(func):
    '''Measure performance of a function'''

    @wraps(func)
    def wrapper(*args, **kwargs):
        tracemalloc.start()
        start_time = perf_counter()
        func(*args, **kwargs)
        current, peak = tracemalloc.get_traced_memory()
        finish_time = perf_counter()
        print(f'Function: {func.__name__}')
        print(f'Method: {func.__doc__}')
        print(f'Memory usage:\t\t {current / 10**6:.6f} MB \n'
              f'Peak memory usage:\t {peak / 10**6:.6f} MB ')
        print(f'Time elapsed is seconds: {finish_time - start_time:.6f}')
        print(f'{"-"*40}')
        tracemalloc.stop()
    return wrapper


@measure_performance
def make_list1():
    '''Range'''

    my_list = list(range(100000))


@measure_performance
def make_list2():
    '''List comprehension'''

    my_list = [l for l in range(100000)]


@measure_performance
def make_list3():
    '''Append'''

    my_list = []
    for item in range(100000):
        my_list.append(item)


@measure_performance
def make_list4():
    '''Concatenation'''

    my_list = []
    for item in range(100000):
        my_list = my_list + [item]


print(make_list1())
print(make_list2())
print(make_list3())
print(make_list4())

# Output

Function: make_list1
Method: Range
Memory usage:		        0.000072 MB 
Peak memory usage:	        3.693040 MB 
Time elapsed is seconds:    0.049359
----------------------------------------

Function: make_list2
Method: List comprehension
Memory usage:		        0.000856 MB 
Peak memory usage:	        3.618244 MB 
Time elapsed is seconds:    0.052338
----------------------------------------

Function: make_list3
Method: Append
Memory usage:		        0.000448 MB 
Peak memory usage:	        3.617692 MB 
Time elapsed is seconds:    0.060719
----------------------------------------

Function: make_list4
Method: Concatenation
Memory usage:		        0.000440 MB 
Peak memory usage:	        4.393292 MB 
Time elapsed is seconds:    61.649138
----------------------------------------

您也可以將裝飾器與類一起使用。讓我們看看如何在 Python 類中使用裝飾器。

在這個例子中,注意沒有@涉及任何字符。使用該__call__方法,在創建類的實例時執行裝飾器。

此類跟蹤查詢 API 的函數已運行的次數。一旦達到限制,裝飾器就會停止執行該函數。

import requests


class LimitQuery:

    def __init__(self, func):
        self.func = func
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.limit = args[0]
        if self.count < self.limit:
            self.count += 1
            return self.func(*args, **kwargs)
        else:
            print(f'No queries left. All {self.count} queries used.')
            return

@LimitQuery
def get_coin_price(limit):
    '''View the Bitcoin Price Index (BPI)'''
    
    url = requests.get('https://api.coindesk.com/v1/bpi/currentprice.json')

    if url.status_code == 200:
        text = url.json()
        return f"${float(text['bpi']['USD']['rate_float']):.2f}"


print(get_coin_price(5))
print(get_coin_price(5))
print(get_coin_price(5))
print(get_coin_price(5))
print(get_coin_price(5))
print(get_coin_price(5))

# Output

$35968.25
$35896.55
$34368.14
$35962.27
$34058.26
No queries left. All 5 queries used.

這個類將跟蹤類的狀態。

讀到這里,這篇“怎么創建和使用Python裝飾器”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

孝感市| 密山市| 盐池县| 龙游县| 茌平县| 安达市| 博乐市| 萨迦县| 南平市| 涞源县| 安阳县| 阿克| 张家港市| 大宁县| 柘荣县| 西安市| 大城县| 博爱县| 长顺县| 白沙| 化德县| 定南县| 赤水市| 渭源县| 手游| 威宁| 垫江县| 凤山市| 大化| 石屏县| 永寿县| 乃东县| 永州市| 康平县| 浦北县| 泰安市| 普兰县| 资溪县| 民勤县| 沂源县| 凤翔县|