这篇文章主要介绍了Python变量作用域LEGB用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
闭包就是,函数内部嵌套函数。而装饰器只是闭包的特殊场景而已,特殊在如果外函数的参数是指向一个,用来被装饰的函数地址时(不一定是地址哈,随意就好),就有了“@xxx”这样的写法,还是蛮有意思的。装饰器的作用是在不改变原函数的代码前提下,额外给原函数填写新功能。写法上来看,还是比较简洁优雅的。
装饰器的通俗写法
#装饰器的通用写法 def(函数): def内部(* args, * * kwargs): 打印(“我们正在检查……”args [0]) 返回func (* args, * * kwargs) 回归内心的 @out def check_2019_nCov(名称): 返回f“{name}是很健康……” tmp=check_2019_nCov(“相伴”) 打印(tmp) #输出 我们正在检查…相伴 现在,相伴非常健康…
给装饰器传参
虽然这种“@”的写法,是要求外函数的参数是一个函数地址,但要达到可以传参,只要再在外面包一层函数(作用是接受参数),这样不就相当于扩大作用空间,拿到参数了呀。
#最外层的函数作用是,给装饰器传递参数 def get_param (* args, * * kwargs): def(函数): def内部(* args, * * kwargs): print(“参数”,args, kwargs) 返回func (* args, * * kwargs) 回归内心的 返回了 @get_param(“相伴”) def check_2019_nCov(名称): 返回f“{name}是很健康……” tmp=check_2019_nCov(“相伴”) 打印(tmp) #输出 得到参数(“相伴”){} 现在,相伴非常健康…
这种个装饰器传递参数的应用场景,在网络应用中,以瓶为例,就是所有的路由url的概念呀,如路线(“/登录”)这样的写法,其原理就是用各种装饰器来实现路由→视图的映射关系的。
仔细一看,整个过程忽略了一个重要的话题,即命名空间,及变量的作用域,或者说命名空间如怎样的。
LEGB法则
<>强命名空间
强>
前篇已经详细阐述过了,Python变量的本质是指针,是对象的引用,而Python中万物皆对象。这个对象是真正存储数据的内存地址,是各种类(数据类型,数据结构)的实例。(变量就是用来引用对象的)差不多这个意思吧。
最为直观的解释:
"名称空间是一个从名称映射到对象”。(变量名和对象的映射)
"最目前名称空间作为Python字典实现。”(大部分命名空间通过字典来实现)
即命名空间是用来避免变量命名冲突的约束。各个命名空间是彼此独立的,一个空间中不能重名,不同空间中是不没有关系的。就跟计算机系统,存储文件是样的逻辑。
因为我在范围(10): 打印(我) #这两句话都用到我了但其各自的空间是不一样的。 (我因为我在范围(100))
-
<李>内置空间:(内置的名字):Python内置名称,如内置函数,异常类…李>
<李>全局空间:(全局名称):常量,模块中定义的名称(类,导入模块)…李>
<李>封闭:可能嵌套在函数内的函数等…李>
<李>局部名称:(地方名):函数中定义的名称(函数内的变量)…李>
Python查找变量顺序为:当地→封闭→全球→内置.
其实,从我个人经验而言,能区分局部和全局的相对性。就好了,基本上。直观上,以一个写代码的py文件为例。最外层有,变量,类定义,函数定义,从从. .进口. .的变量或函数名,这些就是全局变量,最外面的类或者函数,里面是各自的名字空间呀。
# var1是全球 var1=666 def foo (): # var2是局部 var2=666 def foo2 (): #内嵌的局部 var3=666 #打印(var2) 打印(var3) # G→L是找不到的哦 #在foo2中寻找var2是L→E是ok的 #在foo中寻找var2是E→L是不行的
其实很好理解的。就上段代码来说,根据L-E-G-B法,则其实理解一个相对就可以了。
全局与局部
总=0 #全局 def和(a, b): ”“重写内置”和“ 总=a + b 打印(“局部总:“,总) sum (1,1) 打印(“全局总:“,总) #输出 局部总:2 全局总:0Python变量作用域LEGB用法解析