Python 中一切皆对象
Python 中一切皆对象与元类机制 在 Python 中类也是对象,而元类则是创建这些类对象的底层机制,用于在类创建过程中实现高级的自定义与校验逻辑。 Python 中数字、函数、类本身等皆为对象,类是由元类创建的实例。 元类(Metaclass)是类的模板,默认使用内置的 type 类创建其他类。 元类允许开发者在类定义阶段拦截、校验并修改类的属性与行为。 通过继承 type 并覆盖 __ne
在 Python 的面向对象编程与元编程体系中,装饰器(Decorator) 是一种强大且优雅的语法糖。虽然它通常用于函数或方法,但其本质是基于闭包(Closure)和高阶函数(Higher-order function)的一种代码注入机制,旨在“在不修改原对象定义的前提下,为其增加额外功能”。
什么是装饰器?
简单来说,装饰器就是一个接受函数(或类)作为参数,并返回一个新的函数(或类)的函数。它在代码执行时,将原本的目标函数“包装”起来,从而在调用目标函数前后添加自定义逻辑。
核心机制:高阶函数与闭包
Python 的装饰器依赖于两个核心特性:
- 函数是一等公民:函数可以像变量一样被赋值、作为参数传递、作为返回值返回。
- 闭包:内层函数可以引用外层函数的自由变量,即使外层函数已经执行结束。
装饰器的基本语法
最常见的装饰器语法使用 @ 符号,这仅仅是语法糖。以下两段代码是等价的:
使用语法糖:
底层执行过程:
一个简单的装饰器示例
假设我们需要记录函数执行的时间,可以使用装饰器来实现:
装饰器的工作流程图
装饰器的进阶应用
1. 带参数的装饰器
如果装饰器本身需要接收配置参数(如设置日志等级),则需要多嵌套一层函数:
2. 类装饰器
装饰器不仅可以装饰函数,也可以装饰类。类装饰器通常用于修改类的属性或方法。
装饰器 vs 元类 (Metaclass)
在你的上下文背景中,“装饰器”与“元类”常被放在一起讨论,因为它们都是代码“增强”的手段。两者的主要区别在于作用阶段:
- 装饰器:作用于函数或类定义之后。它是对已经创建好的对象进行“包装”。
- 元类:作用于类定义阶段(即
class关键字解析时)。它是直接干预“类”这个对象是如何产生的。
建议深入探索的方向:
functools.wraps:这是编写装饰器时的“标配”,用于保留原函数的元信息(如__name__和__doc__)。- 装饰器栈:多个装饰器叠加时(
@a @b)的执行顺序(从下向上,从内向外)。 - 类作为装饰器:通过实现
__call__方法,将类本身作为装饰器使用。 - 反射与动态编程:结合
getattr、setattr等函数,理解装饰器如何实现动态修改对象的属性。
装饰器是 Python “一切皆对象”理念的集大成者,掌握它可以显著减少代码冗余,并使业务逻辑与横向切面逻辑(如权限检查、日志记录、缓存)实现良好的解耦。