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

Python裝飾器之類裝飾器詳解

 更新時(shí)間:2025年04月27日 10:49:10   作者:鄧瑞軍說HelloWorld  
本文將詳細(xì)介紹Python中類裝飾器的概念、使用方法以及應(yīng)用場(chǎng)景,并通過一個(gè)綜合詳細(xì)的例子展示如何使用類裝飾器,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1. 引言

在Python中,裝飾器是一種允許我們?cè)诓桓淖冊(cè)写a的情況下,動(dòng)態(tài)地增加或修改函數(shù)和類功能的工具。

類裝飾器相較于函數(shù)裝飾器,功能更為強(qiáng)大和靈活,因?yàn)樗鼈儾粌H可以修飾類的方法,還可以修飾類本身。

2. 裝飾器的基本概念

裝飾器是一個(gè)接受函數(shù)或類并返回一個(gè)新函數(shù)或新類的高階函數(shù)。它們通常通過 @ 符號(hào)來使用。

在使用裝飾器時(shí),我們將裝飾器放在被裝飾對(duì)象的上方,這樣裝飾器就會(huì)在對(duì)象創(chuàng)建時(shí)自動(dòng)應(yīng)用。

2.1. 函數(shù)裝飾器復(fù)習(xí)

在介紹類裝飾器之前,我們先簡單回顧一下函數(shù)裝飾器的基本用法。

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

運(yùn)行上述代碼,輸出結(jié)果為:

Something is happening before the function is called.
Hello, Alice!
Something is happening after the function is called.

2.2 類裝飾器的定義和使用

類裝飾器與函數(shù)裝飾器類似,只不過它們接受一個(gè)類作為參數(shù),并返回一個(gè)新類。

最簡單的類裝飾器可以這樣定義:

def class_decorator(cls):
    class WrappedClass(cls):
        def new_method(self):
            print("This is a new method added by the decorator.")
        def existing_method(self):
            print("This method is overridden by the decorator.")
    return WrappedClass

@class_decorator
class MyClass:
    def existing_method(self):
        print("This method exists in the original class.")

obj = MyClass()
obj.new_method()          # 調(diào)用新增的方法
obj.existing_method()     # 調(diào)用被重寫的方法

運(yùn)行上述代碼,輸出結(jié)果為:

This is a new method added by the decorator.
This method is overridden by the decorator.

在這個(gè)例子中,class_decorator 是一個(gè)類裝飾器,它接受一個(gè)類 MyClass 作為參數(shù),并返回一個(gè)新的類 WrappedClass。WrappedClass 繼承自 MyClass,并新增和重寫了一些方法。

3. 類裝飾器的應(yīng)用場(chǎng)景

類裝飾器在實(shí)際開發(fā)中有很多應(yīng)用場(chǎng)景,下面是幾個(gè)常見的例子:

3.1. 自動(dòng)添加屬性

類裝飾器可以用來自動(dòng)為類添加一些屬性。

例如,我們可以創(chuàng)建一個(gè)裝飾器,自動(dòng)為類添加一個(gè) created_at 屬性,記錄對(duì)象的創(chuàng)建時(shí)間。

import datetime

def add_timestamp(cls):
    class WrappedClass(cls):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.created_at = datetime.datetime.now()
    return WrappedClass

@add_timestamp
class MyClass:
    def __init__(self, name):
        self.name = name

obj = MyClass("Alice")
print(obj.name)        # 輸出: Alice
print(obj.created_at)  # 輸出: 對(duì)象的創(chuàng)建時(shí)間

3.2 訪問控制

類裝飾器可以用來控制類的方法訪問權(quán)限。

例如,我們可以創(chuàng)建一個(gè)裝飾器,要求調(diào)用某些方法時(shí)必須有管理員權(quán)限。

def require_admin(cls):
    class WrappedClass(cls):
        def admin_method(self, *args, **kwargs):
            if not self.is_admin:
                raise PermissionError("Admin privileges required")
            return super().admin_method(*args, **kwargs)
    return WrappedClass

@require_admin
class MyClass:
    def __init__(self, is_admin):
        self.is_admin = is_admin

    def admin_method(self):
        print("This is an admin method.")

admin_obj = MyClass(is_admin=True)
admin_obj.admin_method()  # 正常調(diào)用

user_obj = MyClass(is_admin=False)
user_obj.admin_method()   # 拋出 PermissionError

3.3 數(shù)據(jù)驗(yàn)證

類裝飾器可以用來在類方法調(diào)用前進(jìn)行數(shù)據(jù)驗(yàn)證。

例如,我們可以創(chuàng)建一個(gè)裝飾器,驗(yàn)證方法參數(shù)的類型。

def validate_params(cls):
    class WrappedClass(cls):
        def method_with_validation(self, x):
            if not isinstance(x, int):
                raise ValueError("Parameter x must be an integer")
            return super().method_with_validation(x)
    return WrappedClass

@validate_params
class MyClass:
    def method_with_validation(self, x):
        print(f"Received {x}")

obj = MyClass()
obj.method_with_validation(10)  # 正常調(diào)用
obj.method_with_validation("a") # 拋出 ValueError

4. 綜合示例

接下來,我們將通過一個(gè)綜合示例來展示如何使用類裝飾器。

這個(gè)示例將包含一個(gè)日志記錄裝飾器、一個(gè)權(quán)限檢查裝飾器和一個(gè)數(shù)據(jù)驗(yàn)證裝飾器。

import datetime

def log_activity(cls):
    class WrappedClass(cls):
        def __getattribute__(self, name):
            attr = super().__getattribute__(name)
            if callable(attr):
                def logged(*args, **kwargs):
                    print(f"Calling {name} with arguments {args} and {kwargs} at {datetime.datetime.now()}")
                    result = attr(*args, **kwargs)
                    print(f"{name} returned {result}")
                    return result
                return logged
            return attr
    return WrappedClass

def require_permission(permission):
    def decorator(cls):
        class WrappedClass(cls):
            def __getattribute__(self, name):
                attr = super().__getattribute__(name)
                if callable(attr):
                    def secured(*args, **kwargs):
                        if not self.has_permission(permission):
                            raise PermissionError(f"Permission {permission} required")
                        return attr(*args, **kwargs)
                    return secured
                return attr
        return WrappedClass
    return decorator

def validate_params(cls):
    class WrappedClass(cls):
        def method_with_validation(self, x):
            if not isinstance(x, int):
                raise ValueError("Parameter x must be an integer")
            return super().method_with_validation(x)
    return WrappedClass

@log_activity
@require_permission("admin")
@validate_params
class MyClass:
    def __init__(self, is_admin):
        self.is_admin = is_admin

    def has_permission(self, permission):
        return self.is_admin

    def method_with_validation(self, x):
        return f"Received {x}"

# 測(cè)試綜合示例
admin_obj = MyClass(is_admin=True)
print(admin_obj.method_with_validation(10))  # 正常調(diào)用

try:
    admin_obj.method_with_validation("a")  # 拋出 ValueError
except ValueError as e:
    print(e)

user_obj = MyClass(is_admin=False)
try:
    user_obj.method_with_validation(10)  # 拋出 PermissionError
except PermissionError as e:
    print(e)

4.1 輸出結(jié)果

Calling __init__ with arguments (True,) and {} at 2024-07-11 14:23:45.123456
__init__ returned None
Calling method_with_validation with arguments (10,) and {} at 2024-07-11 14:23:45.123456
method_with_validation returned Received 10
Received 10
Calling method_with_validation with arguments ('a',) and {} at 2024-07-11 14:23:45.123456
Parameter x must be an integer
Calling __init__ with arguments (False,) and {} at 2024-07-11 14:23:45.123456
__init__ returned None
Calling method_with_validation with arguments (10,) and {} at 2024-07-11 14:23:45.123456
Permission admin required

4.2 解釋

  1. 日志記錄裝飾器:記錄類的方法調(diào)用,包括輸入?yún)?shù)和返回值。
  2. 權(quán)限檢查裝飾器:檢查用戶是否具有調(diào)用方法的權(quán)限。
  3. 數(shù)據(jù)驗(yàn)證裝飾器:驗(yàn)證方法參數(shù)的類型。

通過這種方式,我們可以在不修改類本身的情況下,為類添加額外的功能。

總結(jié)

類裝飾器是 Python 中一個(gè)非常強(qiáng)大的工具,可以用來擴(kuò)展和修改類的行為。通過類裝飾器,我們可以在不修改原始代碼的情況下為類添加額外的功能。

在實(shí)際開發(fā)中,類裝飾器有很多應(yīng)用場(chǎng)景,包括日志記錄、訪問控制、數(shù)據(jù)驗(yàn)證等。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python圖像特效之模糊玻璃效果

    Python圖像特效之模糊玻璃效果

    這篇文章主要為大家詳細(xì)介紹了Python圖像特效之模糊玻璃效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Python實(shí)現(xiàn)學(xué)生管理系統(tǒng)的代碼(JSON模塊)

    Python實(shí)現(xiàn)學(xué)生管理系統(tǒng)的代碼(JSON模塊)

    這篇文章主要介紹了Python實(shí)現(xiàn)學(xué)生管理系統(tǒng)的代碼(JSON模塊),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Python生成各式各樣的圖像特效實(shí)例

    Python生成各式各樣的圖像特效實(shí)例

    這篇文章主要為大家介紹了Python生成圖像特效,本文重點(diǎn)介紹如何使用python進(jìn)行圖像處理,生成各式各樣的圖像特效,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-10-10
  • Pygame實(shí)戰(zhàn)練習(xí)之飛機(jī)大戰(zhàn)游戲

    Pygame實(shí)戰(zhàn)練習(xí)之飛機(jī)大戰(zhàn)游戲

    飛機(jī)大戰(zhàn)想必是很多人童年時(shí)期的經(jīng)典游戲,我們依舊能記得抱個(gè)老人機(jī)娛樂的場(chǎng)景,下面這篇文章主要給大家介紹了關(guān)于如何利用python寫一個(gè)簡單的飛機(jī)大戰(zhàn)小游戲的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • 使用Python編寫錄屏錄音工具

    使用Python編寫錄屏錄音工具

    這篇文章主要為大家詳細(xì)介紹了如何使用Python編寫一個(gè)錄屏錄音工具,工具界面十分簡單,默認(rèn)是全屏錄屏錄音,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • Python數(shù)據(jù)庫封裝實(shí)現(xiàn)代碼示例解析

    Python數(shù)據(jù)庫封裝實(shí)現(xiàn)代碼示例解析

    這篇文章主要介紹了Python數(shù)據(jù)庫封裝實(shí)現(xiàn)代碼示例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • python公司內(nèi)項(xiàng)目對(duì)接釘釘審批流程的實(shí)現(xiàn)

    python公司內(nèi)項(xiàng)目對(duì)接釘釘審批流程的實(shí)現(xiàn)

    最近把組內(nèi)的一個(gè)項(xiàng)目對(duì)接釘釘審批接口,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • python遍歷數(shù)組的方法小結(jié)

    python遍歷數(shù)組的方法小結(jié)

    這篇文章主要介紹了python遍歷數(shù)組的方法,實(shí)例總結(jié)了兩種Python遍歷數(shù)組的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • Python+Tkinter實(shí)現(xiàn)股票K線圖的繪制

    Python+Tkinter實(shí)現(xiàn)股票K線圖的繪制

    K線圖又稱蠟燭圖,常用說法是“K線”。K線是以每個(gè)分析周期的開盤價(jià)、最高價(jià)、最低價(jià)和收盤價(jià)繪制而成。本文將利用Python+Tkinter實(shí)現(xiàn)股票K線圖的繪制,需要的可以參考一下
    2022-08-08
  • 在Django的URLconf中使用多個(gè)視圖前綴的方法

    在Django的URLconf中使用多個(gè)視圖前綴的方法

    這篇文章主要介紹了在Django的URLconf中使用多個(gè)視圖前綴的方法,Django是Python中最為著名的遵循MVC結(jié)構(gòu)的開發(fā)框架,需要的朋友可以參考下
    2015-07-07

最新評(píng)論