Python高级技巧(七):装饰器
文章目录
- 前言
- 1. 闭包函数和嵌套函数
- 2. 装饰器
-
- 2.1 装饰器的基本用法
- 3. 装饰器的语法糖
-
- 3.1 定义
- 3.2 语法糖的种类
- 3.3 语法糖的使用
- 4. 装饰带参数的函数
-
- 4.1 装饰只有一个参数的函数
- 4.2 装饰未知参数数量的函数
- 5. 带参数的装饰器
- 6.装饰器的嵌套
- 7. 类装饰器
- 8.装饰器的常见应用
-
- 8.1 记录日志
- 8.2 性能测试
- 8.3 权限验证
- 总结
前言
Python装饰器作为Python语言中一项强大而优雅的特性,是每位Python开发者必须掌握的高级编程技巧。它不仅体现了Python"一切皆对象"的哲学思想,更是函数式编程与面向对象编程完美结合的典范。装饰器通过一种非侵入式的方式为现有代码添加新功能,遵循了"开放-封闭"原则,使得代码更加模块化、可维护和可复用。
本文将从基础概念出发,循序渐进地深入探讨装饰器的各个方面。无论您是刚接触装饰器的新手,还是希望深化理解的进阶开发者,本文都将为您提供清晰的学习路径和实用的代码示例。我们将从嵌套函数和闭包的基础知识讲起,逐步深入到装饰器的各种高级用法和实际应用场景,帮助您真正掌握这一强大的Python特性。
1. 闭包函数和嵌套函数
在学习装饰器之前我们先来看看这个闭包函数和嵌套函数
嵌套函数
定义:如果在一个函数的内部还定义了另一个函数,这个函数就叫嵌套函数。外
部的我们叫它外函数,内部的我们叫他内函数。
嵌套函数的代码示例:
def outer_function(outer_param):"""外部函数"""print(f"外部函数被调用,参数为: {outer_param}")# 在外部函数内部定义的函数 -> 嵌套函数def inner_function(inner_param):"""内部函数(嵌套函数)"""print(f"内部函数被调用,参数为: {inner_param}")# 内部函数可以访问外部函数的参数和变量result = outer_param + inner_paramprint(f"内部函数计算结果: {outer_param} + {inner_param} = {result}")return result# 外部函数返回内部函数(注意:不是调用内部函数,所以没有括号)return inner_function# 调用外部函数,它会返回内部函数
inner_func = outer_function(10)
print(f"outer_function返回的类型: {type(inner_func)}")
print(f"inner_func的名称: {inner_func.__name__}")# 现在调用内部函数
result = inner_func(5)
print(f"最终结果: {result}")print("\n" + "="*50 + "\n")
输出结果:
外部函数被调用,参数为: 10
outer_function返回的类型: <class 'function'>
inner_func的名称: inner_function
内部函数被调用,参数为: 5
内部函数计算结果: 10 + 5 = 15
最终结果: 15==================================================
解释说明:
外部函数 outer_function 接受一个参数 outer_param
内部函数 inner_function 定义在外部函数内部,可以访问外部函数的参数
外部函数返回内部函数本身(不是调用结果),这就是函数工厂模式
当我们调用 outer_function(10) 时,它返回一个绑定 outer_param=10 的内部函数
随后调用这个返回的函数时,它仍然记得外部函数的作用域
闭包函数
定义:如果内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过
程叫做闭包,里面的内函数是闭包函数
闭包函数的代码示例
def counter():"""创建一个计数器闭包"""count = 0 # 这个变量将被内部函数"记住"def increment():# 使用nonlocal关键字声明count不是局部变量,而是外部函数的变量nonlocal countcount += 1return count# 返回内部函数,它"关闭"了外部作用域中的count变量 -> 这就是闭包return increment# 创建两个独立的计数器
counter1 = counter()
counter2 = counter()print("计数器1:")
print(counter1()) # 输出: 1
print(counter1()) # 输出: 2
print(counter1()) # 输出: 3print("\n计数器2:")
print(counter2()) # 输出: 1 (独立的计数)
print(counter2()) # 输出: 2print("\n" + "="*50