Python高级特性之闭包与装饰器实例详解

落日邮差
落日邮差
发布时间:2026-10-12| 2人浏览过
原创

本文深入解析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程序设计工作有所帮助。

相关标签:

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

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 算法库。