Python函数之LEGB和匿名函数(8)

您所在的位置:网站首页 函数里的u是什么意思 Python函数之LEGB和匿名函数(8)

Python函数之LEGB和匿名函数(8)

#Python函数之LEGB和匿名函数(8)| 来源: 网络整理| 查看: 265

一、背景引入

外部对内部可见,向内穿透,在内部可以看到外部的变量。使用的时候就近原则,函数内部变量对外是不可见的。

Python中提出了LEGB这个东西,这个就是变量解析

Python函数之LEGB和匿名函数(8)_匿名函数

LEGB原则是什么呢?

二、LEGB原则

变量名解析原则原则原则就是LEGB,对名词进行解释

Local:本地作用域、局部作用域的local命名空间。函数调用时创建,调用结束消亡 Enclosing:Python2.2时引入了嵌套函数,实现了闭包,这个就是嵌套函数的外部 函数的命名空间。 Global:全局作用域,即一个模块的命名空间。模块被import时创建,解释器退出时 消亡。 Build-in:内置模块的命名空间,生命周期从python解释器启动时创建到解释器退出 时消亡。例如print(open), print和open都是内置的变量。

所以一个名词的查找顺序就是LEGB

这个的意思就是说,解释器碰到变量的时候,怎么解析它,现在L里面的范围没有的话,就继续向外找。直到找到为止,没有找到则报错。由内及外

三、函数的销毁

定义一个函数就是生成一个函数对象, 函数名指向的就是函数对象。

可以使用del语句删除函数,使其引|用计数减1。

可以使用同名标识符覆盖原有定义,本质上也是使其引用计数减1。

Python程序结束时,所有对象销毁。

函数也是对象,也不例外,是否销毁,还是看引|用计数是否减为0。

所谓的各种删除就是引用计数减1

四、匿名函数

什么叫匿名函数呢?所谓匿名就是没有名字,隐藏名字没有名称,匿名函数没有名称的函数。在python当中它不仅仅是没有名字的函数,没有名字的函数该如何调用呢?

在python 中使用Lambda表达式构建匿名函数,python中表达式不能复杂,Lambda还要另外一个名字叫做单行函数,需要一行完成。

python匿名函数的功能,是逊于其他语言的

怎么去写匿名函数呢?看下面代码

fn=lambda : 0 这个会返回一个匿名函数,用标识符fn记住了这个匿名函数 def fn(x): x+=1 return x 把上面的fn函数改造成匿名函数 lambda x:x+1 这样两个函数就等价了 lambda 函数中不能出现=,更不能出现return 冒号后只能是表达式,表达式计算的结果作为该匿名函数return的返回值 冒号前写参数 表达式的值是做为函数返回值,进行返回。

lambda  后面加参数列表但是不要括号,有多个参数使用逗号隔开,冒号后面不能写x=+1。

因为lambda中不能出现等于号(=)

在改造一个函数

def add(x,y): return x+y (lambda x,y :x+y)(4,5) 这个的意思就是说,前面返回了一个函数,后面(4,5)是给的实参。这样就能 计算4+5了。 (4,5)就表示调用了 参数列表有缺省值需要向后放(x=5,y)这样写参数会报错,参数传参原则和前面 学的传参数原则一致 要这样理解匿名函数,表达式的x+y,要自己带入它完成的是return x+y 所有匿名函数的表达式都要这样考虑,自己脑子中带入一个 (lambda *,x,y: x+y)(y=4,x=5) lambda表达式 一般不这样使用,使用在高阶函数中 y和x接收关键字传参数,(y=4,x=5) 这个表示进行调用 上面小括号表示改变优先级问题

继续看代码

[lambda *args,args](4,5,6) 用中括号括起来这个匿名函数,这个执行后会报错为什么? []() 这样中括号后面加小括号,解释起来就是直接调用了这个列表,列表是不能 直接调用的。 这个意思就是列表中存放了一个匿名函数对象,列表中只有着一个元素 这样继续修改代码,加了[0] [lambda *args,args][0](4,5,6) 加这个[0]的意思就是从列表中拿到第1个元素的值,他是一个函数,这个函数, 可以加括号调用,可以接受4 5 6 三个参数,收集在了元组当中。 输出 (4, 5, 6) 函数对象后加小括号()就表示调用了

在继续看匿名函数的其他形式

lambda *args:(x for x in args)) 这个会返回一个函数 (lambda *args:(x for x in args)) (1,2,3) 加了小括号()就表示调用了,会返回一个生成器对象 用next可以访问这个生成器对象 在继续看代码 (lambda *args:[x for x in args])(4,5,6) 这个会输出一个列表[4,5,6] lambda *args:list(args)(4,5,6) 上面这两个都把参数放在列表中进行迭代,着两个的表达是一样的 (lambda *args:[args])(4,5,6) 这个输出什么? 自己认为可能返回一个列表[4,5,6],但是并不是这样的。它实际上返回的是 [(4,5,6)] 这是列表中包含了一个元组对象,上面着两个是不同的形式 (lambda *args: {x + 1 for x in args})(4, 5, 6) 输出 {5,6,7} 输出元素的位置不能确定 这个会输出什么? (lambda *args: {x + 1 for x in args}) (range(5)) 这里会报错,因为这个args没有做参数解构,range(5)就是一个元素, 这个元素被*args收集,收集之后变为一个元组,元组中就一个元素 就是range(5), range(5)是没办法加1的 (lambda *args: {x for x in args}) (range(5)) 这个可以输出 {range(5)} (lambda *args: {x + 1 for x in args}) (*range(5)) range前加 * 进行结构就可以了 这样args接收的就是 {0,1,2,3,4}

我们继续在看匿名函数的应用:

高阶函数会用到匿名函数

比如现在相对列表排序,但是数据类型不一致,该怎么办? sorted(['a',1,'b',12,'c',28],key=str) 转类型就可以了,都变为字符串类型 现在用lambda函数来实现这个str: 这个函数能接收一个参数,返回一个字符串,一次只处理一个参数 lambda item:str(item) 这样一来不管送进来什么参数,返回的都是str类型 key后面写匿名函数函数 这两个是等价的 sorted(['a',1,'b',12,'c',28],key=str) sorted(['a',1,'b',12,'c',28],key=lambda x:str(x)) 继续引申问题,我现在非得想用整数类型比较,该怎么办? 下面这样key=int,直接语法错误,该怎么办? sorted(['a',1,'b',12,'c',28],key=int) 语法错误 在重新写,必须用整数比较 sorted(['a',1,'b',12,'c',28],key=int) def a(x): if isinstance(x,str): y=int(x,16) else: y=x return y 通过对这个函数的改写来实现 sorted(['a', 1, 'b', 12, 'c', 28], key=lambda x: int(x, 16) if isinstance(x, str) else x)

匿名函数通常用于高阶函数传参数的时候,使用lambda表达式,往往能简化代码

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3