了解Python中的装饰器:从入门到精通

python小知识2026年6月7日2

了解Python中的装饰器:从入门到精通

装饰器是Python中一个非常强大且灵活的特性,它允许程序员在不改变函数本身的情况下扩展或修改函数的行为。本文将带你从零开始,了解装饰器的工作原理,常见的基本操作,并深入介绍@dataclass和@property装饰器的用法。

一、装饰器的工作原理

装饰器实际上是一种高级函数,它接收一个函数作为参数,并返回一个新的函数。一个简单的装饰器如下:

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

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

say_hello()

输出:

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

在这个例子中,@my_decorator相当于say_hello = my_decorator(say_hello)。装饰器模式允许我们在不修改原函数代码的情况下,为函数添加额外的功能。

二、常用的基本操作

1. 装饰器传参

有时候我们需要给装饰器传递参数,这时可以使用带参数的装饰器:

def repeat(num_times):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator_repeat

@repeat(num_times=3)
def greet(name):
    print(f"Hello {name}")

greet("World")

输出:

Hello World
Hello World
Hello World

2. 类装饰器

除了函数,装饰器还可以用于类:

def singleton(cls):
    instances = {}
    def getinstance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    pass

a = MyClass()
b = MyClass()

print(a is b)  # True

三、@dataclass 装饰器

Python 3.7引入了dataclasses模块,其中的@dataclass装饰器简化了类的定义,尤其是数据类。数据类是一种特殊的类,主要用于存储数据。

from dataclasses import dataclass

@dataclass
class Person:
    name: str
    age: int

p = Person(name="Alice", age=30)
print(p)  # Person(name='Alice', age=30)

@dataclass装饰器自动为类生成__init__、__repr__、__eq__等方法,大大简化了代码。

四、property 装饰器

property装饰器用于将方法转换为只读属性。它提供了一种优雅的方式来定义属性的getter和setter方法。

class Celsius:
    def __init__(self, temperature=0):
        self._temperature = temperature

    @property
    def temperature(self):
        return self._temperature

    @temperature.setter
    def temperature(self, value):
        if value < -273.15:
            raise ValueError("Temperature below -273.15 is not possible")
        self._temperature = value

c = Celsius()
c.temperature = 37
print(c.temperature)  # 37

try:
    c.temperature = -300
except ValueError as e:
    print(e)  # Temperature below -273.15 is not possible

在这个例子中,@property装饰器使得temperature方法可以像属性一样被访问,同时通过@temperature.setter定义了setter方法。

五、总结

本文介绍了Python装饰器的基本概念和用法,包括函数装饰器、类装饰器、带参数的装饰器,以及@dataclass和property装饰器。通过这些例子和解释,相信你已经对装饰器有了初步的了解并能够在实际项目中有效使用它们。装饰器是Python的一项强大特性,掌握它将使你的代码更加优雅和可维护。