首页 > 编程语言 >Python函数之LEGB和匿名函数(8)

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

时间:2023-04-03 19:00:59浏览次数:40  
标签:函数 Python LEGB args 列表 匿名 参数 lambda

一、背景引入

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

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表达式,往往能简化代码

 


标签:函数,Python,LEGB,args,列表,匿名,参数,lambda
From: https://blog.51cto.com/u_14743944/6167097

相关文章

  • Python3内置函数之G系列
    1、getattr()getattr()函数是Python内置函数之一,用于获取一个对象的指定属性值。2、globals()globals()是Python内置函数之一,用于返回当前全局作用域中所有变量的字典。这个字典包含了所有已定义的全局变量,键为变量名,值为对应的值。可以通过修改这个字典中的变量来更新全......
  • linux下的c++filt 命令查找未定义符号的函数名
    我们知道,在C++中,是允许函数重载的,也就引出了编译器的namemangling机制,今天我们要介绍的c++filt命令便与此有关。   对于从事linux开发的人来说,不可不知道c++filt命令的使用。    在linux开发中,如果要调用基础模块库,就要包含对应的头文件,并在makefile中指......
  • Flask 和pythonweb框架介绍、flask快速使用、登录,显示用户信息小案例、配置文件方式、
    Flask和pythonweb框架介绍、flask快速使用、登录,显示用户信息小案例、配置文件方式、路由系统Flask和pythonweb框架介绍Flask和pythonweb框架的区别:Django框架: 大而全,内置的app很多,第三方的app很多Flask框架: 小而精,没有过多的内置app,只能完成web框架的基本功能,很多功能......
  • opencv-python 4.10.3. 直方图3:2D直方图
    介绍我们学习计算并绘制了一维直方图。它之所以被称为一维,是因为我们只考虑一个特征,即像素的灰度强度值。但在二维直方图中,需要考虑两个特征。通常,它用于查找颜色直方图,其中两个特征是每个像素的色调值和饱和度值。OpenCV中的2D直方图它很简单,使用相同的函数cv.calcHist()计......
  • Python3内置函数之E系列
    1、enumerate()在Python中,enumerate()是一个内置函数,用于将一个可迭代对象转换为一个枚举对象,该对象包含每个元素的索引和对应的值。enumerate()函数返回的是一个由元组组成的迭代器,每个元组包含两个元素,第一个元素是元素的索引,第二个元素是元素的值。 2、eval()在Python中,e......
  • Python常见面试题015.请实现一个如下功能的函数
    015.请实现一个如下功能的函数来自python黑魔法题目实现一个add函数,可以"反复"调用,得到累加的结果defadd(num):...add(1)#输出1add(2)#输出2add(1)(2)#输出3(即1+2)add(1)(2)(3)#输出6思考一开始我想到的是用一个参数,类型是list,能保存用户的传......
  • 几何计算函数库(转)
    原文地址:https://www.cnblogs.com/lovebay/p/10470238.html计算几何几何函数库-------------------------------------------------------------------------------------------------------------------------------导引1.常量定义和包含文件2.基本数据结构3.精度控制㈠点的......
  • MYSQL中CAST函数
    MYSQL中CAST函数CAST函数用于将值从一种转换数据类型的方法语法:SELECTCAST(xAStype);x:要处理的数据type:要转换的数据类型,取值下方表格type取值值描述DATE将value转换成'YYYY-MM-DD'格式TIME将value转换成'HH:MM:SS'格式DATETIME将value转换......
  • 函数式编程-高阶函数
    函数本身也可以赋值给变量,即:变量可以指向函数  那么函数名是什么呢?函数名其实是指向函数的变量!对于abs()这个函数,完全可以把函数名abs看成变量,它指向一个可以计算绝对值的函数! 既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函......
  • C++黑马程序员——P55. 函数的分文件编写
    函数分文件编写一般有4个步骤1.创建后缀名为.h的头文件2.创建后缀名为.cpp的源文件3.在头文件中写函数的声明4.在源文件中写函数的定义 1.创建后缀名为.h的头文件右键项目的“头文件”文件夹->添加->新建项->然后中间选“头文件(.h)”,下面起个名字,添加2.......