欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python基礎(chǔ)教程之裝飾器詳解

 更新時(shí)間:2023年06月29日 09:24:11   作者:陸理手記  
眾所周知,Python裝飾器是一種常見的元編程特性,在本教程中,我們將深入探討Python裝飾器的基本概念、語法及其應(yīng)用,并利用實(shí)際例子加深理解,感興趣的小伙伴快跟隨小編一起了解一下吧

眾所周知,Python裝飾器是一種常見的元編程特性,它提供了一種方便的方法來修改或增強(qiáng)現(xiàn)有函數(shù)的行為,而不需要修改函數(shù)的源代碼,保持代碼的可讀性和可維護(hù)性。在本教程中,我們將深入探討Python裝飾器的基本概念、語法及其應(yīng)用,并利用實(shí)際例子加深理解。

1.什么是裝飾器模式

裝飾器模式是一種允許在運(yùn)行時(shí)動(dòng)態(tài)地改變對(duì)象或類功能的技術(shù)。在Python中,裝飾器實(shí)際是一種特殊的函數(shù),裝飾器函數(shù)接收一個(gè)函數(shù)作為參數(shù),并返回一個(gè)修改后的函數(shù),新函數(shù)具有與原始函數(shù)相同的名稱和參數(shù)。在調(diào)用原始函數(shù)之前或之后,可執(zhí)行一些額外的操作,如計(jì)時(shí)、日志記錄或修改參數(shù)等。下面是一個(gè)簡單的裝飾器示例,它用于在函數(shù)調(diào)用前后顯示信息。

def add_info(func):
    def wrapper(*args, **kwargs):
        print(f"Call function {func.__name__} with args {args} and kwargs {kwargs}")
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} returned {result}")
        return result
    return wrapper
@add_info
def add(x, y):
    return x + y
# 調(diào)用add函數(shù)
print(add(3, 5))

輸出結(jié)果

Call function add with args (3, 5) and kwargs {}
Function add returned 8
8

在上述示例中,add_info是一個(gè)裝飾器函數(shù),它定義了一個(gè)名為wrapper的嵌套函數(shù)。在調(diào)用被裝飾的函數(shù)add時(shí),實(shí)際上會(huì)先執(zhí)行add_info函數(shù),并傳入add函數(shù)作為參數(shù),然后將其返回的wrapper函數(shù)作為修改后的add函數(shù)使用。在wrapper函數(shù)內(nèi)部,我們首先打印了一些調(diào)試信息,然后通過func(*args, **kwargs)調(diào)用原始函數(shù),并返回其返回值。因此,在調(diào)用add函數(shù)時(shí),我們會(huì)對(duì)其輸入輸出進(jìn)行了一些額外的監(jiān)測和記錄。

2.復(fù)合裝飾器

除了上述示例中展示的基本裝飾器模式之外,Python裝飾器還有一些其他的高級(jí)用法,例如多個(gè)裝飾器的復(fù)合、裝飾器的參數(shù)傳遞、類裝飾器等。下面再來看一下例子:

# 多個(gè)裝飾器的復(fù)合
def hello(func):
    def wrapper(*args, **kwargs):
        print("Hello,")
        return func(*args, **kwargs)
    return wrapper
def world(func):
    def wrapper(*args, **kwargs):
        print("World!")
        return func(*args, **kwargs)
    return wrapper
@hello
@world
def greet():
    print("How are you?")
greet()

通過上述例子,我們可以實(shí)現(xiàn)使用多個(gè)不同的裝飾器來組成函數(shù)的裝飾鏈,每個(gè)裝飾器負(fù)責(zé)一項(xiàng)特定的任務(wù)。

3.裝飾器參數(shù)傳遞

我們還可以向裝飾器傳遞參數(shù),使其更加靈活,以適應(yīng)不同的使用場景。

# 裝飾器的參數(shù)傳遞
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for i in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator
@repeat(3)
def hi(name):
    print(f"Hi, {name}")
hi("Alice")

輸出:

Hi, Alice
Hi, Alice
Hi, Alice

在上述示例中,我們定義了一個(gè)裝飾器工廠repeat,它接收一個(gè)times參數(shù),并返回一個(gè)新的裝飾器decorator。在decorator中,我們使用for循環(huán)來執(zhí)行被裝飾函數(shù)3次。這樣,我們就可以為同一個(gè)函數(shù)應(yīng)用多個(gè)不同的裝飾器,以實(shí)現(xiàn)更加靈活的裝飾器功能。

4.類裝飾器

我們還可以使用類裝飾器來實(shí)現(xiàn)更復(fù)雜的裝飾器邏輯,除了上面介紹的函數(shù)裝飾器,我們還可以將裝飾器實(shí)現(xiàn)為類。實(shí)現(xiàn)裝飾器類時(shí),我們需要在該類中實(shí)現(xiàn)__init__()__call__()方法。

# 類裝飾器
class MyDecorator:
    def __init__(self, func):
        self.func = func
    def __call__(self, *args, **kwargs):
        print("Do something before function execution")
        result = self.func(*args, **kwargs)
        print("Do something after function execution")
        return result
@MyDecorator
def my_func():
    print("My function")
my_func()

在上述示例中,我們定義了一個(gè)類MyDecorator來實(shí)現(xiàn)裝飾器,其中__init__()方法用于接收被裝飾的函數(shù)my_func__call__()方法用于實(shí)現(xiàn)裝飾器的邏輯。與函數(shù)裝飾器類似,我們可以在__call__()方法中執(zhí)行一些額外的操作,例如打印調(diào)試信息、記錄日志等。

5.裝飾器的實(shí)際用途

裝飾器可用于許多實(shí)際用途,比如:

  • 計(jì)時(shí):測量函數(shù)執(zhí)行時(shí)間;
  • 日志記錄:記錄函數(shù)調(diào)用時(shí)的日志信息;
  • 緩存:緩存函數(shù)的結(jié)果,以避免重復(fù)計(jì)算;
  • 輸入驗(yàn)證:檢查函數(shù)參數(shù)是否符合預(yù)期。

以下是幾個(gè)具體的示例。

1.用裝飾器計(jì)時(shí)函數(shù)執(zhí)行時(shí)間:

import time
def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time} seconds to run.")
        return result
    return wrapper
@timer
def slow_function():
    time.sleep(2)
slow_function()

輸出:

slow_function took 2.0058863162994385 seconds to run.

2.用裝飾器記錄函數(shù)調(diào)用信息:

def logger(func):
    import logging
    loggingigasicConfig(filename="log.txt", level=logging.INFO)
    def wrapper(*args, **kwargs):
        logging.info(f"Function {func.__name__} was called with args={args} and kwargs={kwargs}.")
        result = func(*args, **kwargs)
        logging.info(f"Function {func.__name__} returned {result}.")
        return result
    return wrapper
@logger
def add(a, b):
    return a + b
add(3, 5)

這個(gè)例子中,我們在wrapper函數(shù)中使用Python的日志模塊記錄函數(shù)調(diào)用信息和返回結(jié)果。我們可以在一個(gè)名為log.txt的文件中看到輸出。

3.用裝飾器實(shí)現(xiàn)輸入驗(yàn)證:

def validate_inputs(func):
    def wrapper(*args, **kwargs):
        for arg in args:
            if noteisinstance(arg, int):
                raise TypeError("All arguments must be integers.")
        for value in kwargs.values():
            if noteisinstance(value, int):
                raise TypeError("All keyword arguments must be integers.")
        return func(*args, **kwargs)
    return wrapper
@validate_inputs
def sum_numbers(a, b, c):
    return a + b + c
sum_numbers(1, 2, 3)
sum_numbers("1", "2", c=3)  # This line will raise a TypeError.

這個(gè)裝飾器用于驗(yàn)證函數(shù)的輸入?yún)?shù)是否符合預(yù)期。如果有任何參數(shù)不是整數(shù),裝飾器將拋出TypeErrors異常。

6.總結(jié)

上一篇教程:Python基礎(chǔ)教程:多線程編程

Python的裝飾器模式是一種強(qiáng)大的技術(shù),它可擴(kuò)展函數(shù)的功能,而不需要在函數(shù)本身的代碼中創(chuàng)建復(fù)雜的邏輯。通過使用裝飾器,我們可以輕松地構(gòu)建更復(fù)雜和功能強(qiáng)大的應(yīng)用程序。在本教程中,我們介紹了Python裝飾器的基本概念、語法及其應(yīng)用,并舉了一些實(shí)際例子,希望這些內(nèi)容能夠幫助您更深入地理解Python裝飾器并應(yīng)用于實(shí)際項(xiàng)目中。

以上就是Python基礎(chǔ)教程之裝飾器詳解的詳細(xì)內(nèi)容,更多關(guān)于Python裝飾器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python 出現(xiàn)錯(cuò)誤TypeError: ‘NoneType’ object is not iterable解決辦法

    Python 出現(xiàn)錯(cuò)誤TypeError: ‘NoneType’ object is not iterable解決辦法

    這篇文章主要介紹了Python 出現(xiàn)錯(cuò)誤TypeError: ‘NoneType’ object is not iterable解決辦法的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Python代碼風(fēng)格與編程習(xí)慣重要嗎?

    Python代碼風(fēng)格與編程習(xí)慣重要嗎?

    實(shí)現(xiàn)高內(nèi)聚,低耦合、結(jié)構(gòu)清晰不臃腫、可讀性高、數(shù)據(jù)冗余性低、高復(fù)用、易擴(kuò)展的代碼,并非易事.上到設(shè)計(jì)模式,下到某個(gè)類、方法、函數(shù)的構(gòu)造.在這里我分享一下我自己的代碼設(shè)計(jì),編寫風(fēng)格,讓我們互相學(xué)習(xí),需要的朋友可以參考下
    2021-06-06
  • python的json中方法及jsonpath模塊用法分析

    python的json中方法及jsonpath模塊用法分析

    這篇文章主要介紹了python的json中方法及jsonpath模塊用法,結(jié)合實(shí)例形式分析了Python json相關(guān)模塊與常見方法使用技巧,需要的朋友可以參考下
    2019-12-12
  • python3 kmp 字符串匹配的方法

    python3 kmp 字符串匹配的方法

    這篇文章主要介紹了python3 kmp 字符串匹配的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • Python中不可錯(cuò)過的五個(gè)超有用函數(shù)

    Python中不可錯(cuò)過的五個(gè)超有用函數(shù)

    在本文中,我們用代碼詳細(xì)說明了Python中超實(shí)用的5個(gè)函數(shù)的重要作用,這些函數(shù)雖然簡單,但卻是Python中功能最強(qiáng)大的函數(shù),下面一起來看看文章的詳細(xì)介紹吧,希望對(duì)你的學(xué)習(xí)有所幫助
    2022-01-01
  • Python os.path.exists()函數(shù)總是返回false的解決方案

    Python os.path.exists()函數(shù)總是返回false的解決方案

    這篇文章主要介紹了Python os.path.exists()函數(shù)總是返回false的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Python3監(jiān)控疫情的完整代碼

    Python3監(jiān)控疫情的完整代碼

    這篇文章主要介紹了Python3監(jiān)控疫情的完整代碼,代碼簡單易懂,非常不錯(cuò)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • python中hasattr()、getattr()、setattr()函數(shù)的使用

    python中hasattr()、getattr()、setattr()函數(shù)的使用

    這篇文章主要介紹了python中hasattr()、getattr()、setattr()函數(shù)的使用方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 淺談Python中進(jìn)程的創(chuàng)建與結(jié)束

    淺談Python中進(jìn)程的創(chuàng)建與結(jié)束

    這篇文章主要介紹了淺談Python中進(jìn)程的創(chuàng)建與結(jié)束,但凡是硬件,都需要有操作系統(tǒng)去管理,只要有操作系統(tǒng),就有進(jìn)程的概念,就需要有創(chuàng)建進(jìn)程的方式,需要的朋友可以參考下
    2023-07-07
  • Python Pandas 轉(zhuǎn)換unix時(shí)間戳方式

    Python Pandas 轉(zhuǎn)換unix時(shí)間戳方式

    今天小編就為大家分享一篇Python Pandas 轉(zhuǎn)換unix時(shí)間戳方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12

最新評(píng)論