欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Day4 回调 闭包 匿名lambda 迭代器——python学习之路

程序员文章站 2022-03-11 12:43:40
...

回调函数

  • 回调函数将函数作为一个参数进行传递
  • 即定义一个函数,要求这个函数中的一个参数是另一个函数
# 定义回调函数
def cal(x,y,opt):
	'''
	对两个数进行运算,并打印结果
	:param x: 数字一
	:param y: 数字二
	:param opt: 选择运算方式
	:return: 无返回值
	'''
	print(opt(x,y))

# 定义两个被调函数
def add(x,y):
	return x+y

def sub(x,y):
	return x-y

cal(20,15,sub)

#(输出) 5

闭包函数

在一个函数内返回了一个内函数(这个内函数即闭包函数),并且这个返回的内函数还使用了外函数中的局部变量

  • 闭包特点:
  1. 在外函数中定义了局部变量,并且在内部函数中使用了这个局部变量
  2. 在外函数中返回了内函数,返回的内函数就是闭包函数
  3. 主要在于保护了外函数中的局部变量,既可以被使用,又不会被破坏
  4. 一般来说,当对象中只有一个方法时,这时使用闭包是更好的选择
# 通过闭包实现只有通过上课出勤才能修改平时分变量mark
def attend():
	mark = 0				# 特点1:定义局部变量
	# 定义加平时分的内函数
	def add():
		nonlocal mark		# 特点1:在内部函数中使用了外函数的局部变量
		mark += 10
		print(f'当前平时分是:{mark}')
	return add				# 特点2:在外函数中返回了内函数

# mark = 100				# 特点3:无法直接修改mark,保护局部变量
stu = attend()				# 返回值为内函数add,return add ⇒ stu = add
stu()						# stu() == add()
stu()

#(输出)
# 当前的平时分是:10
# 当前的平时分是:20
  • 使用 函数名.__closure__检测一个函数是否为闭包函数
  • 如果是闭包函数将返回 cell
print(attend().__closure__)

#(输出)	(< cell at ... >,)

匿名函数

不使用def定义,而是使用lambda表达式定义的函数,没有名字,即匿名函数

lambda表达式

  • lambda表达式被称为一行代码,不是代码块
  • lambda表达式只能访问自己的形参
  • 作为一行代码,不能胜任太复杂的逻辑,功能相对单一
  • 定义方式:lambda [参数列表] : 返回值
# 给两个参数,做相加操作
res = lambda x,y:x+y
print(res(2,4))

#(输出) 6
# 带有分支结构的lambda表达式
# 语法:lambda 参数列表:真区间 if 判断语句 else 假区间
res = lambda age:"小兰" if age=="新一" else "哀酱"
print(res('新一'))

#(输出) 小兰

迭代器

  • 迭代器是一个可以记住访问遍历的位置的对象,是访问集合元素的一种方式
  • 从集合一个元素开始访问,直到集合中的所有元素被访问完毕
  • 迭代器只能从前往后一个一个的遍历,不能后退
  • 能被next()函数调用,并不断返回下一个值的对象称为迭代器(Iterator 迭代器)

通过 iter() 生成迭代器

  • 功能:把可迭代的对象,转为一个迭代器对象
  • 参数:可迭代的对象(str,list,tuple,dict,set,range…)
  • 返回值:迭代器对象

tip:迭代器一定是一个可迭代的对象,但可迭代对象不一定是迭代器

迭代器取值的特点:取出一个少一个,直到都取完,再取会报错(StopIteration错误)
迭代器取值的方案:

  1. next() 调用一次获取一次,直到数据被取完
  2. list()  使用list函数直接取出迭代器中的所有数据
  3. for    使用for循环遍历迭代器的数据
child = ['小学','初中','高中','大学']
iterchild = iter(child)		# 将可迭代对象child转为迭代器
# 1. next()
print(next(iterchild))		#(输出) 小学
print(next(iterchild))		#(输出) 初中

# 2. list()
print(list(iterchild))		#(输出)	['高中','大学']		因为上面next取走了前两个

# 3. for
iterchild = iter(child)		# 原来的迭代器内没有内容了,再生成一个新的
for item in iterchild:
	print(item)
#(输出) 小学 初中 高中 大学

检测迭代器和可迭代对象的方法

使用 dir() 函数查看对象的属性列表,如果只有__iter__函数则是可迭代的如果__iter__函数和__next__函数都有则为迭代器

# dir(数据): 返回这个数据可以执行的所有操作
# __iter__	可迭代的
# __iter__ __next__ 迭代器
child = ['小学','初中','高中','大学']
iterchild = iter(child)

print(dir(child))
print(dir()iterchild)

(推荐)

  • isinstance(obj,cls)
    用于判断obj对象是否由cls这个类实例化出来的。
    若实例化对象的类继承了父类,判断对象isintance父类也返回True。
# 需要通过 collections.abc 导入包 Iterable,Iterator
from collections.abc import Iterable, Iterator

child = ['小学','初中','高中','大学']
iterchild = iter(child)
print(isinstance(child, Iterable))		#(输出) True
print(isinstance(child, Iterator))		#(输出)	False
print(isinstance(iterchild, Iterable))	#(输出)	True
print(isinstance(iterchild, Iterator))	#(输出)	True