Python高级特性之闭包与装饰器实例详解
本文深入解析Python中的闭包与装饰器机制。通过函数引用、变量作用域及嵌套定义等核心概念,阐明闭包的构成原理。重点演示装饰器在不修改原代码前提下扩展功能的多种场景,包括处理返回值、函数参数、通用版本及类装饰器,并解析多层装饰器的执行顺序与逻辑。
本文详细介绍Python语言中的高级特性:闭包与装饰器。内容涵盖核心概念解析与代码实例,旨在为读者提供清晰的参考与学习路径。
闭包概念解析
1. 函数参数的基本机制:
(1) 函数名本身存储的是该函数在内存中的地址; (2) 通过函数名加括号(如 func())调用时,执行的是函数内部的代码逻辑; (3) 函数名实质上是函数代码空间的引用,当将函数名赋值给其他变量时,传递的是该引用(即引用传递)。
def func01():
print("func01 is show")
test = func01
print(func01)
print(test)
test()
运行结果如下:

2. 闭包的定义与特征:
(1) 内部函数具备访问外部函数变量的能力;
(2) 闭包是一种嵌套定义的函数结构。当外层函数运行时,才会定义内层函数,并将内层函数的引用返回给外层函数的调用者(即闭包外层函数的返回值是内层函数名);
(3) 由内部函数以及其使用的外部函数提供的变量共同构成的整体,被称为闭包。
def func_out(rate):
def func_in(money):
print(rate * money)
return func_in
usa_money = func_out(0.7)
usa_money(100)
usa_money(200)
具体执行结果如下:

装饰器基础
装饰器的核心作用是在不修改函数原有源代码的前提下,为函数添加新的功能。通常情况下,装饰器本身就是一个闭包结构。
1. 基础装饰器实现:
# 在不改变函数的原有代码的前提下 给函数添加新的功能
def func_out(func):
def func_in():
print("验证")
func()
return func_in
@func_out
def login():
print("登录")
# 有装饰器 装饰器下面正好是一个函数
# login = func_out(login) 重点
login()
当 @func_out 装饰器作用于 login 函数时,系统会执行以下逻辑:
login = func_out(login)
此时直接执行 func_out 内部的代码,其中 func 参数指向原始的 login 函数地址,并返回内层函数的引用。具体表现为:
login = func_out(login) = func_in
因此,调用 login() 实际上等同于执行 func_in(),具体逻辑为:
print('验证')
func() # func指原login函数的地址
通过上述机制,实现了在不改变原函数代码的情况下,成功为函数添加了新功能。
运行结果如下:

2. 处理有返回值的函数装饰:
def func_out(func):
def func_in():
# ret = func()
# def login():
# return 100
return func()
return func_in
@func_out
def login():
return 100
# login() ==> func_in()
# func ==> 原始的login
f = login()
print(f)
3. 处理有参数函数的装饰:
def func_out(func):
def func_in(a):
func(a)
return func_in
@func_out
def login(a):
print(a)
# login() ==> func_in()
# func ==> 原始的login
login(10)
4. 通用版装饰器实现:
def func_out(func):
def func_in(*args,**kwargs):
return func(*args,**kwargs)
return func_in
@func_out
def login(*args,**kwargs):
print(args)
print(kwargs)
# login() ==> func_in()
# func ==> 原始的login
login(10,20,age = "17",name="123")
5. 类装饰器实现:
class Foo(object):
def __init__(self, func):
self.func = func
def __call__(self):
print("验证")
self.func()
@Foo
def login():
print("登录")
# login = Foo(login)
login()
6. 多重装饰器应用:
def func_out01(func01):
print("func_out01 is show")
def func_in01():
print("func_in01 is show")
func01()
return func_in01
def func_out02(func02):
print("func_out02 is show")
def func_in02():
print("func_in02 is show")
func02()
return func_in02
@func_out02 # login = func_out02(login)
@func_out01 # login = func_out01(login)
def login():
print("login is show")
login()
运行结果如下:
由于只有当 @ 符号后的闭包名对应函数时,装饰器逻辑才会生效,因此 func_out1 会先对函数进行装饰,func_out2 随后进行装饰。这意味着外层函数先执行 func_out1,后执行 func_out2。鉴于 func_out1 先装饰,func_out2 后装饰,func_out1 装饰后的结果是先输出 func_in1 内的语句,再输出原始 login 函数;而 func_out2 装饰后,执行顺序变为先输出 func_in2 的语句,再输出经 func_out1 装饰后的 login 函数。最终执行顺序为:func_in2 → func_in1 → login。

7. 向装饰器传递参数的实现:
def route(参数):
print(参数)
def func_out(func):
def func_in():
func()
return func_in
return func_out
@route(参数)
def index():
return "index is show"
更多关于Python相关技术的深入内容,感兴趣的读者可查阅本站专题:《Python面向对象程序设计入门与进阶教程》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python编码操作技巧总结》及《Python入门与进阶经典教程》。
希望本文所述的实例与分析能对读者的Python程序设计工作有所帮助。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









