偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Python 中這七個(gè)類裝飾器技巧,裝飾類而不是方法!

開發(fā)
今天咱們聊聊Python中的類裝飾器,但不是常見(jiàn)的函數(shù)裝飾器哦,而是專門用來(lái)裝飾類的技巧!很多初學(xué)者可能只知道裝飾器可以修飾方法或函數(shù),其實(shí)它還能“改造”整個(gè)類呢。

大家好!今天咱們聊聊Python中的類裝飾器,但不是常見(jiàn)的函數(shù)裝飾器哦,而是專門用來(lái)裝飾類的技巧!很多初學(xué)者可能只知道裝飾器可以修飾方法或函數(shù),其實(shí)它還能“改造”整個(gè)類呢。比如給類動(dòng)態(tài)添加屬性、實(shí)現(xiàn)單例模式、甚至優(yōu)化日志系統(tǒng)等功能,都可以通過(guò)類裝飾器完成。接下來(lái)我會(huì)用7個(gè)小節(jié)詳細(xì)講解,從基礎(chǔ)到高級(jí),手把手教你掌握這些技巧!

一、理解裝飾器的基本概念與作用

1. 裝飾器是什么?

裝飾器是Python中非常強(qiáng)大的工具,它允許我們?cè)诓恍薷脑写a的情況下為函數(shù)或類添加額外的功能。比如,你想在函數(shù)執(zhí)行前后打印日志,裝飾器就能輕松搞定!來(lái)看個(gè)簡(jiǎn)單例子:

def my_decorator(func):
    def wrapper():
        print("執(zhí)行前的操作")
        func()
        print("執(zhí)行后的操作")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

輸出:

執(zhí)行前的操作
Hello!
執(zhí)行后的操作

裝飾器的核心就是“包裝”函數(shù),讓它變得更強(qiáng)大。接下來(lái),我們會(huì)深入學(xué)習(xí)如何用裝飾器來(lái)裝飾類,而不是方法哦!

二、使用類裝飾器的基本語(yǔ)法

1. 類裝飾器的定義與作用

類裝飾器其實(shí)很好理解!它本質(zhì)上是一個(gè)帶有 __call__ 方法的類,可以用來(lái)“包裝”其他類。當(dāng)一個(gè)類被裝飾時(shí),裝飾器會(huì)攔截對(duì)這個(gè)類的所有實(shí)例化操作。舉個(gè)例子:

class MyDecorator:
    def __init__(self, cls):# 接收被裝飾的類
        self.cls = cls

    def __call__(self, *args, **kwargs):# 攔截實(shí)例化操作
        print("類裝飾器被調(diào)用了!")
        return self.cls(*args, **kwargs)

@MyDecorator  # 等價(jià)于 MyClass = MyDecorator(MyClass)
class MyClass:
    def __init__(self, name):
        self.name = name

obj = MyClass("Python")  # 輸出:類裝飾器被調(diào)用了!
print(obj.name)  # 輸出:Python

這段代碼展示了類裝飾器的基本結(jié)構(gòu)和用法。簡(jiǎn)單來(lái)說(shuō),裝飾器通過(guò) __call__ 方法控制類的實(shí)例化過(guò)程。是不是很酷?

三、類裝飾器中__init__和__call__方法的使用技巧

1. 理解__init__和__call__的作用

在類裝飾器中,__init__用于初始化裝飾器本身的參數(shù),而__call__則負(fù)責(zé)對(duì)被裝飾的類進(jìn)行處理。兩者配合可以讓類裝飾器功能更強(qiáng)大!來(lái)看個(gè)例子:

class MyDecorator:
    def __init__(self, func):
        # 初始化時(shí)接收被裝飾的類
        self.func = func

    def __call__(self, *args, **kwargs):
        # 在這里可以修改類的行為
        print("裝飾器執(zhí)行前的操作")
        instance = self.func(*args, **kwargs)  # 實(shí)例化被裝飾的類
        print("裝飾器執(zhí)行后的操作")
        return instance


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


obj = MyClass("Python")  # 輸出:裝飾器執(zhí)行前的操作 裝飾器執(zhí)行后的操作
print(obj.name)  # 輸出:Python

通過(guò)這段代碼,你可以清楚地看到裝飾器如何在類實(shí)例化前后添加額外邏輯!

四、如何通過(guò)類裝飾器添加屬性或方法

1. 類裝飾器可以輕松擴(kuò)展類功能

有時(shí)候,我們希望在不修改原始類代碼的情況下,為類動(dòng)態(tài)添加屬性或方法。這時(shí)候,類裝飾器就派上用場(chǎng)了!下面是一個(gè)簡(jiǎn)單的例子:

class AddFeatures:
    def __init__(self, cls):
        self.cls = cls  # 接收被裝飾的類

    def __call__(self, *args, **kwargs):
        instance = self.cls(*args, **kwargs)  # 創(chuàng)建實(shí)例
        
        # 動(dòng)態(tài)添加屬性
        instance.new_attribute = "我是新增的屬性"
        
        # 動(dòng)態(tài)添加方法
        def new_method(self):
            return"我是新增的方法"
        
        instance.new_method = new_method.__get__(instance)  # 綁定方法到實(shí)例
        
        return instance


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


obj = MyClass("測(cè)試")
print(obj.new_attribute)  # 輸出:我是新增的屬性
print(obj.new_method())  # 輸出:我是新增的方法

2. 這段代碼的工作原理

  • AddFeatures 是一個(gè)類裝飾器,它接收一個(gè)類作為參數(shù)。
  • 在 __call__ 方法中,我們創(chuàng)建了被裝飾類的實(shí)例。
  • 然后通過(guò)直接賦值的方式為實(shí)例添加了一個(gè)新屬性 new_attribute 和一個(gè)新方法 new_method。
  • 最后返回這個(gè)增強(qiáng)后的實(shí)例。

這種方式非常適合在開發(fā)中動(dòng)態(tài)擴(kuò)展類的功能,而無(wú)需修改原始類的定義!是不是很酷?

五、利用類裝飾器實(shí)現(xiàn)單例模式的設(shè)計(jì)

1. 單例模式是什么?

單例模式是一種設(shè)計(jì)模式,確保一個(gè)類只有一個(gè)實(shí)例,并提供全局訪問(wèn)點(diǎn)。在 Python 中,我們可以通過(guò)類裝飾器來(lái)實(shí)現(xiàn)這一功能!

2. 使用類裝飾器實(shí)現(xiàn)單例模式

下面是一個(gè)簡(jiǎn)單的例子,展示如何通過(guò)類裝飾器實(shí)現(xiàn)單例模式:

class Singleton:  # 定義一個(gè)類裝飾器
    def __init__(self, cls):
        self._cls = cls  # 保存被裝飾的類
        self._instance = None# 初始化實(shí)例為None

    def __call__(self, *args, **kwargs):# 每次調(diào)用類時(shí)觸發(fā)
        if self._instance isNone:  # 如果沒(méi)有創(chuàng)建過(guò)實(shí)例
            self._instance = self._cls(*args, **kwargs)  # 創(chuàng)建實(shí)例
        return self._instance  # 返回唯一實(shí)例


@Singleton  # 使用類裝飾器
class DatabaseConnection:
    def __init__(self, url):
        self.url = url

# 測(cè)試代碼
db1 = DatabaseConnection("http://example.com")
db2 = DatabaseConnection("http://test.com")

print(db1 is db2)  # 輸出:True
print(db1.url)  # 輸出:http://example.com

3. 代碼解析

  • Singleton 類是裝飾器,它會(huì)在第一次調(diào)用時(shí)創(chuàng)建類的實(shí)例,并保存下來(lái)。
  • 后續(xù)每次調(diào)用都會(huì)返回同一個(gè)實(shí)例,確保了單例模式的實(shí)現(xiàn)。

在實(shí)際開發(fā)中,這種技巧非常適合管理數(shù)據(jù)庫(kù)連接、配置文件等需要共享資源的場(chǎng)景!

六、高級(jí)技巧:動(dòng)態(tài)修改類的行為與功能

1. 使用類裝飾器動(dòng)態(tài)添加方法

類裝飾器可以用來(lái)動(dòng)態(tài)地為類添加方法,而不需要直接修改類的定義。比如下面這個(gè)例子:

def add_method(cls):
    def new_method(self):
        return "This is a dynamically added method!"
    cls.dynamic_method = new_method  # 動(dòng)態(tài)添加方法
    return cls

@add_method
class MyClass:
    pass

obj = MyClass()
print(obj.dynamic_method())  # 輸出: This is a dynamically added method!

通過(guò)類裝飾器,我們成功為 MyClass 添加了一個(gè)新方法 dynamic_method。

2. 修改類的屬性或行為

除了添加方法,類裝飾器還能修改類的屬性或行為。看這個(gè)例子:

def modify_class(cls):
    cls.modified_attribute = "Modified by decorator"
    return cls

@modify_class
class AnotherClass:
    original_attribute = "Original value"

print(AnotherClass.original_attribute)  # 輸出: Original value
print(AnotherClass.modified_attribute)  # 輸出: Modified by decorator

在這個(gè)例子中,我們用裝飾器給 AnotherClass 增加了一個(gè)新的屬性 modified_attribute。

3. 動(dòng)態(tài)注入日志功能

高級(jí)一點(diǎn)的應(yīng)用是為類注入日志功能,方便調(diào)試和監(jiān)控:

import logging

def log_calls(cls):
    original_init = cls.__init__
    def new_init(self, *args, **kwargs):
        logging.info(f"Initializing {cls.__name__} with args={args}, kwargs={kwargs}")
        original_init(self, *args, **kwargs)
    cls.__init__ = new_init
    return cls

@log_calls
class LoggedClass:
    def __init__(self, value):
        self.value = value

logging.basicConfig(level=logging.INFO)
LoggedClass(42)  # 控制臺(tái)輸出: INFO:root:Initializing LoggedClass with args=(42,), kwargs={}

通過(guò)這個(gè)裝飾器,每次實(shí)例化 LoggedClass 時(shí)都會(huì)記錄日志,非常實(shí)用!

七、實(shí)戰(zhàn)案例:使用類裝飾器優(yōu)化日志記錄系統(tǒng)

1. 類裝飾器實(shí)現(xiàn)日志記錄功能

在開發(fā)中,日志記錄是不可或缺的一部分。通過(guò)類裝飾器,我們可以優(yōu)雅地為類添加日志功能。比如,當(dāng)一個(gè)類被實(shí)例化或方法被調(diào)用時(shí),自動(dòng)記錄相關(guān)信息。

class LogDecorator:
    def __init__(self, cls):
        self.cls = cls

    def __call__(self, *args, **kwargs):
        print(f"Creating instance of {self.cls.__name__}")
        instance = self.cls(*args, **kwargs)
        return instance


@LogDecorator
class Calculator:
    def add(self, a, b):
        return a + b


calc = Calculator()  # 輸出: Creating instance of Calculator

2. 動(dòng)態(tài)記錄方法調(diào)用

我們還可以進(jìn)一步擴(kuò)展類裝飾器,記錄類中每個(gè)方法的調(diào)用情況。

class MethodLogger:
    def __init__(self, cls):
        self.cls = cls
        self._wrap_methods()

    def _wrap_methods(self):
        for attr_name, attr_value in self.cls.__dict__.items():
            if callable(attr_value):
                setattr(self.cls, attr_name, self._log_and_call(attr_value))

    def _log_and_call(self, func):
        def wrapper(*args, **kwargs):
            print(f"Calling {func.__name__} with args: {args}, kwargs: {kwargs}")
            return func(*args, **kwargs)
        return wrapper

    def __call__(self, *args, **kwargs):
        return self.cls(*args, **kwargs)


@MethodLogger
class MathOperations:
    def add(self, a, b):
        return a + b

    def multiply(self, a, b):
        return a * b


math = MathOperations()
math.add(5, 3)  # 輸出: Calling add with args: (5, 3), kwargs: {}
math.multiply(4, 6)  # 輸出: Calling multiply with args: (4, 6), kwargs: {}

這種實(shí)戰(zhàn)技巧不僅可以幫助我們快速定位問(wèn)題,還能讓代碼更加清晰、易維護(hù)!

責(zé)任編輯:趙寧寧 來(lái)源: 手把手PythonAI編程
相關(guān)推薦

2022-06-15 10:24:13

Pytho裝飾器代碼

2024-05-20 09:26:42

Python裝飾器函數(shù)

2020-11-17 09:10:44

裝飾器

2025-05-08 08:10:00

Python函數(shù)調(diào)用代碼

2022-09-07 10:20:05

Python裝飾類

2024-11-06 16:13:00

Python單例模式

2010-02-01 17:50:32

Python裝飾器

2023-02-07 07:47:52

Python裝飾器函數(shù)

2025-01-10 08:38:16

2024-09-12 15:32:35

裝飾器Python

2021-04-11 08:21:20

Python@property裝飾器

2025-01-22 15:58:46

2022-10-24 07:31:53

Python編程裝飾器

2016-11-01 09:24:38

Python裝飾器

2022-09-19 23:04:08

Python裝飾器語(yǔ)言

2024-05-10 12:33:06

flask裝飾器

2023-04-19 15:29:53

通信技巧Vue 3開發(fā)

2025-03-21 08:20:00

數(shù)據(jù)清洗Python編程

2017-04-13 10:58:32

Python開發(fā)者

2025-04-18 08:50:57

項(xiàng)目裝飾器日志
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)