Python 装饰器实战:从基础到类装饰器的完整指南

宋时安
宋时安
发布时间:2026-10-14| 6人浏览过
原创

本文深入解析 Python 装饰器的多种用法,涵盖无参与有参装饰器的实现原理。重点演示如何利用 @wraps 保持函数元数据,以及如何通过判断参数类型实现带参与不带参装饰器的自适应调用。此外,还介绍了记录函数入参出参的高级技巧及类装饰器的编写方法,帮助开发者掌握 Python 高级特性。

Python 装饰器基础:无参与有参场景

首先介绍最简单的无参装饰器场景。当装饰器本身不需要接收任何额外参数时,调用方式最为直接,无需进行额外的函数调用操作。


def log1(func):
  func()
@log1
def test():
  print('test:')

接下来讨论带有参数的被装饰函数情况。此时装饰器需要能够接收并传递这些参数给原始函数,确保功能不被破坏。


def log2(func):
  def inner(*args, **kwargs):
    func(*args, **kwargs)
  return inner
@log2
def test(num):
  print('testlog2:',num,test.__name__)
test(20) #相当于log(test(20))

在使用装饰器时,一个常见的问题是原始函数的元数据(如名称)会被覆盖。通过引入 可以确保装饰器修饰后的函数保留原始的 name 属性值,这对于调试和日志记录至关重要。

不带参数的装饰器实现

不带参数的装饰器是最基础的形式,其核心逻辑是接收一个函数作为参数,并返回一个新的函数包装器。


def log3(func):
  @wraps(func)
  def inner(*args, **kwargs,):
    func(*args, **kwargs)
  return inner
@log3
def test(num):
  print('testlog3:',num,test.__name__)
test(30) #相当于log(test(30))

带参数的装饰器设计

带参数的装饰器允许在装饰器定义时传入配置信息,这需要通过多层嵌套函数来实现,外层接收参数,内层接收函数。


def log4(level):
  def log(func):
    @wraps(func)
    def inner(*args, **kwargs,):
      if level == "warn":
        print("%s is running" % func.__name__)
      func(*args, **kwargs)
    return inner
  return log
@log4(level="warn")
def test(num):
  print('testlog4:', num, test.__name__)
test(40)

自适应装饰器:兼容有参与无参调用

为了实现代码的通用性,可以设计一种自适应装饰器,使其既能像无参装饰器那样直接调用,也能像有参装饰器那样接收参数。这通常通过判断传入参数的类型来实现。


def log(arg):
  if callable(arg): # 判断参入的参数是否是函数,不带参数的装饰器调用这个分支
    def log3(func):
      @wraps(func)
      def inner(*args, **kwargs, ):
        func(*args, **kwargs)
      return inner
    return log3
  else:
    def log4(func):
      @wraps(func)
      def inner(*args, **kwargs,):
        if arg == "warn":
          print("%s is running" % func.__name__)
        func(*args, **kwargs)
      return inner
    return log4
@log(arg=None)
def test(num):
  print('testlog:', num, test.__name__)
test(0)

记录入参出参的调试装饰器

除了控制流程,装饰器还可以用于记录函数的执行细节。例如,在函数执行前后打印入参和出参,有助于调试和分析函数行为。


def log5(func):
  def inner(*args, **kwargs):
    print('入参:',func.__name__, args, kwargs)
    res =func(*args, **kwargs)
    print('出参:',func.__name__, res)
    return res
  return inner
@log5
def test(num):
  print('testlog5:', num, test.__name__)
  return num
print(test(50))

类装饰器的实现与应用

除了函数形式的装饰器,Python 还支持类装饰器。通过实现 魔术方法,可以将类实例用作装饰器,提供更复杂的逻辑封装能力。


class Loging:
  def __init__(self,level):
    self.level = level

  def __call__(self,func):
    @wraps(func)
    def inner(*args, **kwargs):
      if self.level == "warn":
        self.notify(func)
      func(*args, **kwargs)
    return inner

  def notify(self,func):
    print ("%s is running" % func.__name__)


@Loging(level="warn")
def test(num):
  print('testLoging:', num, test.__name__)
test(0)

以上就是 Python 装饰器的核心使用示例与详细解析,涵盖了从基础到高级的应用场景。更多关于 Python 装饰器的深度资料,欢迎持续关注本站发布的其他技术文章。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。