Python LEGB 作用域、闭包与装饰器核心原理解析

Elena
Elena
发布时间:2026-10-12| 1人浏览过
原创

本文深入解析 Python 的 LEGB 变量查找规则,阐明 Local、Enclosing、Global 及 Built-in 的作用域层级。详细讲解闭包的构成条件及其在封装与代码复用中的价值,并通过示例展示如何利用闭包实现参数化函数生成。最后,结合语法糖 @deco 详解装饰器的工作原理,包括函数对象的传递、替换及执行流程,帮助开发者掌握 Python 函数式编程的核心技巧。

详解 Python 中 LEGB 规则、闭包机制及装饰器原理

LEGB 查找顺序:Local > Enclosing > Global > Built-in

  • L(Local):局部作用域,即函数内部定义的区域
  • E(Enclosing):嵌套作用域,指外层函数与内嵌函数之间的区域
  • G(Global):全局作用域,即模块级别的作用域
  • B(Built-in):内置作用域,包含 Python 预定义的名字

Python 闭包概念解析

1. 闭包定义:内部函数引用了外部(enclosing)作用域中的变量

2. 函数的本质与属性

  • 函数在 Python 中是一个对象
  • 函数执行完毕后,其局部变量通常会被回收
  • 函数作为对象具有属性
  • 函数具备返回值
passline = 60
def func(val):
  if val >= passline:
    print ('pass')
  else:
    print ('failed')
  def in_func():
    print (val)
  in_func()
  return in_func

f = func(89)
f()
print (f.__closure__)

一般情况下的变量生命周期

def f_100(val):
  passline = 60
  if val >= passline:
    print ('pass')
  else:
    print ('failed')

def f_150(val):
  passline = 90
  if val >= passline:
    print ('pass')
  else:
    print ('failed')

f_100(89)
f_150(89)

闭包的具体表现形式

def set_passline(passline):
  def cmp(val):
    if val >= passline:
      print ('Pass')
    else:
      print ('failed')
  return cmp

f_100 = set_passline(60)
f_150 = set_passline(90)
f_100(89)
f_150(89)

闭包机制:内部函数通过引用 enclosing 作用域的变量,将该变量传递至内部函数的 __closure__ 属性中

闭包的主要作用:

  • 实现数据封装
  • 提高代码复用性

Python 闭包进阶示例

求和逻辑演示

def my_sum(*arg):
  if len(arg) == 0:
    return 0
  for val in arg:
    if not isinstance(val,int): # 有一个非int则返回0
      return 0
  return sum(arg)

def my_average(*arg):
  if len(arg) == 0:
    return 0
  for val in arg:
    if not isinstance(val,int): # 有一个非int则返回0
      return 0
  return sum(arg)/len(arg)

print (my_sum(1,2,3,4,5))
print (my_sum(1,2,3,4,5,'6'))
print (my_aveage(1,2,3,4,5))
print(my_average())

闭包的实际应用场景

def my_sum(*arg):
  return sum(arg)
def my_average(*arg):
  return sum(arg)/len(arg)

def dec(func):
  def in_dec(*arg): # my_sum
    print ('in dec arg= ',arg)
    if len(arg) ==0:
      return 0
    for val in arg:
      if not isinstance(val, int):
        return 0
    return func(*arg)  # 闭包,存在于in_dec函数中的__closure__中,所以可以调用
  return in_dec

my_sum = dec(my_sum)  # 传参

print(my_sum (1,2,3,4,5))
print(my_sum (1,2,3,4,5,'6'))
# my_sum就是in_dec函数,会先执行参数类型判断,然后执行__closure__中的函数my_sum

Python 装饰器基础

  1. 装饰器用于包装或增强现有函数
  2. 装饰器返回一个新的函数对象
  3. 原被装饰函数的标识符将指向装饰器返回的函数对象
  4. 语法糖 @deco 的使用方式

使用装饰器的具体方式

def dec(func):
  def in_dec(*arg): # my_sum
    print ('in dec arg= ',arg)
    if len(arg) ==0:
      return 0
    for val in arg:
      if not isinstance(val, int):
        return 0
    return func(*arg)  # 闭包,存在于in_dec函数中的__closure__中,所以可以调用
  return in_dec  # 如果没有返回值,则my_sum调用装饰器后为None

# my_sum = dec(my_sum)  # 不手动传参
@dec     # 装饰器将my_sum作为参数传入dec,并返回一个新的函数赋值给my_sum
def my_sum(*arg):
  return sum(arg)
def my_average(*arg):
  return sum(arg)/len(arg)

print(my_sum (1,2,3,4,5))
print(my_sum (1,2,3,4,5,'6'))

另一个装饰器应用示例

def deco(func):
  def in_deco(x,y):
    print ('in deco')
    func(x,y)
  print ('call deco')
  return in_deco

@deco
def bar(x, y):
  print ('in bar',x+y)

bar(1,2)

以上为 Python 中 LEGB 规则、闭包及装饰器的详细介绍。如有疑问,欢迎留言或前往社区交流讨论。本站提供更多 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 算法库。