一、生成器【重点掌握】
# 1.概念 """ 问题: 列表:一次性将所有的元素全部定义出来,如果在还需要访问其中的几个元素,则大量的内存空间会被浪费 如:生成一个列表,其中有10万个元素,但是仅仅需要访问前五个元素 解决方案: 如果需要使用前n个元素,则只有前n个元素会占用内存空间, 在Python中,将这种一边使用,一边计算的机制被称为生成器【generator】 生成器的定义方式: a.将列表推导式中的[]----》() b.函数结合yield,定义函数生成器 """ # 1.定义方式一 # 列表推导式 list1 = [i ** 2 for i in range(6)] print(list1,type(list1)) # [0, 1, 4, 9, 16, 25] <class 'list'> ge1 = (i ** 2 for i in range(6)) print(ge1,type(ge1)) # <generator object <genexpr> at 0x101f0c9a8> <class 'generator'> # 2.访问生成器中的元素 # a.next() print(next(ge1)) print(next(ge1)) print(next(ge1)) print(next(ge1)) print(next(ge1)) print(next(ge1)) # 注意:如果生成器中的元素全部获取完毕,继续获取,则会报错StopIteration # print(next(ge1)) # b.for # for n in ge1: # print(n) # c.list() # print(list(ge1)) # 3.定义方式二 # a # return表示函数的返回值 def test1(): return 10 r1 = test1() print(r1,type(r1)) # 10 <class 'int'> # b. # 注意:只要在函数内部出现yield关键字,则该函数表示一个函数生成器,yield关键字后面的数据将是生成器中的元素 def test2(): yield 10 r2 = test2() print(r2,type(r2)) # <generator object test2 at 0x10a379a20> <class 'generator'> print(next(r2)) # c. def test3(): yield 10 yield 20 yield 30 r3 = test3() # for n in r3: # print(n) # d. def test4(n): for i in range(n): yield i ** 2 # 获取一个生成器中的4个元素 r4 = test4(10) print(next(r4)) print(next(r4)) print(next(r4)) print(next(r4)) # 分别获取4个生成器的第0个元素 print(next(test4(5))) print(next(test4(5))) print(next(test4(5))) print(next(test4(5))) # 注意:函数生成器每调用一次,都表示生成了一个新的生成器
二、可迭代对象和迭代器【面试题】
""" 【面试题】简述可迭代对象和迭代器之间的区别和联系 区别: 可迭代对象:Iterable,可以直接作用于for循环的对象【可以使用for循环遍历其中元素的对象】 如:list,tuple,dict,set,str,range(),generator等 迭代器:Iterator,可以直接作用于for循环,或者可以通过next()获取下一个元素的对象 如:generator 联系: 迭代器一定是可迭代对象,但是可迭代对象不一定是迭代器 可以通过系统功能iter()将不是迭代器的可迭代对象转换为迭代器 """ from collections import Iterable,Iterator # isinstance(变量,类型):判断一个变量是否是指定的数据类型 # 1 print(isinstance([3,4],Iterable)) print(isinstance((3,4),Iterable)) print(isinstance({'a':10},Iterable)) print(isinstance({3,4},Iterable)) print(isinstance("fajg",Iterable)) print(isinstance((i for i in range(3)),Iterable)) print(isinstance(range(3),Iterable)) print("*" * 10) # 2. print(isinstance([3,4],Iterator)) print(isinstance((3,4),Iterator)) print(isinstance({'a':10},Iterator)) print(isinstance({3,4},Iterator)) print(isinstance("fajg",Iterator)) print(isinstance(range(3),Iterator)) print(isinstance((i for i in range(3)),Iterator)) print("*" * 10) # 3. print(isinstance(iter([3,4]),Iterator)) print(isinstance(iter((3,4)),Iterator)) print(isinstance(iter({'a':10}),Iterator)) print(isinstance(iter({3,4}),Iterator)) print(isinstance(iter("fajg"),Iterator)) print(isinstance(iter(range(3)),Iterator))
三、装饰器【重点掌握】
1.基本使用
#1.概念 """ 已知一个函数,如果需要给该函数增加新的功能,但是不希望修改原函数, 在Python中,这种在代码运行期间动态执行的机制被称为装饰器【decorator】 装饰器的作用:为已经存在的函数或类添加额外的功能 装饰器的本质:实际上就是一个闭包,内部函数访问外部函数中的变量【函数】 """ # 1.闭包 def func1(a): def func2(): print(a) func2() func1(4) def func1(a): def func2(): print(a) return func2 f = func1(23) f() # 2.基本语法:原函数没有参数 # 需求:给test函数增加新的功能,但是不能修改test def test(): # 1 11 print("拼搏到无能为力,坚持到感动自己") # 装饰器的书写步骤 # a.书写闭包 # b.给外部函数设置参数,该参数表示需要被装饰的函数 def outter1(func): # 2 4 print("outter~~~11111") def inner1(): # 5 9 print("inner~~~11111") # d.调用原函数 func() # test() # 10 # e.增加新的功能 print("new~~~~") # 12 return inner1 # 6 # c.调用外部函数 f1 = outter1(test) # func--->test f1---->inner1 # 3 7 # f.调用内部函数 f1() # 8 13 outter1(test)() print("*" * 30) # 3.原函数有参数 # 需求:给下面的函数增加新的功能,该功能可以做年龄的校验,如果为负数,则变成相反数 def get_age(age): print(f"年龄:{age}") def wrapper1(func): def check_age(n): # 增加新的功能:校验年龄 if n < 0: n = -n # 调用原函数 func(n) # get_age() return check_age f1 = wrapper1(get_age) # func --->get_age f1--->check_age f1(-20) # check_age() f1(10) # 注意:如果原函数有参,在内部函数中增加功能的时候, # 如果需要对原函数的参数进行相应的运算,则需要给装饰器的内部函数设置参数 print("*" * 50) # 4.@xxx,xxx表示装饰器的外部函数的函数名,只需要将@xxx作用于指定的函数,则该装饰器可以装饰指定的函数 # 注意1:使用@xxx的方式进行装饰,则装饰器必须先存在,然后才能使用 # 注意2:@xxx只会对就近的函数起到装饰作用 def wrapper2(func): print("外部函数被调用了~~~~~") def check_age(n): print("内部函数被调用了~~~~") # 增加新的功能:校验年龄 if n < 0: n = -n # 调用原函数 func(n) return check_age @wrapper2 # 调用外部函数,f1 = wrapper2(get_age) def get_age(age): print(f"年龄:{age}") get_age(-20) # 调用内部函数,f1(-20) """ 工作原理: @wrapper2:相当于调用装饰器的外部函数,将原函数传参给func,同时将内部函数的引用返回,原函数的函数名指向内部桉树 get_age(-20) :调用的是装饰器的内部函数 """ # 练习【面试题】:书写一个装饰器,统计一个函数的执行时间 import time print(time.time()) # 时间戳:获取当前时间距离1970.1.1 00:00:00的秒数 # a. def test(): for i in range(100000): pass def wrapper(func): def get_time(): # 开始时间 start = time.time() # 调用原函数 func() # 结束时间 end = time.time() return round(end - start,4) return get_time f = wrapper(test) print(f()) # b def wrapper11(func): def get_time(): # 开始时间 start = time.time() # 调用原函数 func() # 结束时间 end = time.time() return round(end - start,4) return get_time @wrapper11 def test(): for i in range(100000): pass print(test())
2.进阶使用
# 一、基本使用 # 1. def test(): print("11111") def outter(func): def inner(): func() print("new~~~~~") return inner f = outter(test) f() # 2.推荐使用 def wrapper(func): def inner(): func() print("new~~~222") return inner @wrapper # 相当于 text = wrapper(text) def text(): print("2222") text() # 调用inner print("*" * 30) # 二、进阶使用 # 1.同一个装饰器装饰多个函数 # 特点:给多个不同的函数增加同一个新的功能,为了满足不同函数的需求,装饰器的内部函数设置不定长参数 def wrapper1(func): def inner(*args,**kwargs): # 打包 func(*args,**kwargs) # 拆包 print("new~~~~") return inner @wrapper1 def test1(): print("test~~1111") test1() @wrapper1 def test2(a): print("test~~222",a) test2(3) @wrapper1 def test3(a,b,c): print("test~~3333",a,b,c) test3(3,4,5) # 【面试题】书写一个装饰器,可以统计任意一个函数的执行时间 import time def wrapper(func): def get_time(*args,**kwargs): start = time.time() func(*args,**kwargs) end = time.time() return round(end - start,5) return get_time @wrapper def test2(): return "abc" t = test2() print(t) print("*" * 30) # 2.【面试题】多个装饰器装饰同一个函数 # 特点:给同一个函数同时增加多个新的功能 def wrapper1(func1): def inner1(*args,**kwargs): print("第1个装饰器~~~~~start") func1(*args,**kwargs) print("第1个装饰器~~~~~end") return inner1 def wrapper2(func2): def inner2(*args,**kwargs): print("第2个装饰器~~~~~start") func2(*args,**kwargs) print("第2个装饰器~~~~~end") return inner2 def wrapper3(func3): def inner3(*args,**kwargs): print("第3个装饰器~~~~~start") func3(*args, **kwargs) print("第3个装饰器~~~~~end") return inner3 @wrapper1 @wrapper2 @wrapper3 def test(): print("test~~~~~~~~~~~~") test() # inner1() """ @wrapper3 def test(): pass 工作原理:test原---》func3 test--->inner3 @wrapper2 @wrapper3 def test(): pass 工作原理:inner3---->func2 test---->inner2 @wrapper1 @wrapper2 @wrapper3 def test(): pass 工作原理:inner2--->func1 test----->inner1 """
659

被折叠的 条评论
为什么被折叠?



