Python LEGB 作用域、闭包与装饰器核心原理解析
本文深入解析 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 装饰器基础
- 装饰器用于包装或增强现有函数
- 装饰器返回一个新的函数对象
- 原被装饰函数的标识符将指向装饰器返回的函数对象
- 语法糖 @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 相关文章,建议搜索查阅,感谢阅读,希望能对大家有所帮助,感谢支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













