python中常遇到的问题(Python|生成器(逐次生成迭代器元素)和装饰器(装饰一个函数))python初学 / python装饰器与生成器...

wufei123 发布于 2024-05-14 阅读(34)

1 生成器(generator)我们可以通过列表解析方法来创建列表,但如果列表中的元素很多时,则会占用很大的内存资源如果程序仅需要访问其中的几个元素,则绝大多数元素所占用的空间都被浪费了生成器(generator)是能够按照解析表达式逐次产生出数据集合中数据项元素的函数。

在Python中,利用生成器,可不必创建完整的数据集合,从而节省存储空间生成器函数与普通函数的差别主要在于:生成器函数中利用yield关键字生成数据项,而不是用return返回数据项生成器函数用循环遍历时,可以用__next__()方法获取yield生成的数据项。

生成器函数与变通函数的执行流程不同普通函数是顺序执行的,遇到return语句或最后一行语句就返回而生成器函数在每次调用__next__()方法的时候才执行,遇到yield语句返回,再次执行时不是从头开始,而是从上次返回的yield语句处继续执行。

生成器是用来创建Python序列的一个对象使用它可以迭代庞大的序列,且不需要在内存中创建和存储整个序列通常,生成器是为迭代器产生数据的如range()函数返回在特定区间的自然数序列,如以下语句可以累加从1到100:。

>>> sum(range(1,101))5050每次迭代生成器时,它会记录上一次调用的位置,并且返回下一个值这一点和普通的函数是不一样的,一般函数都不会记录前一次调用,而且都会在函数的第一行开始执行如果你想创建一个比较大的序列,使用生成器推导的代码会很长,这时可以尝试写一个生成器函数。

生成器函数和普通函数类似,但是它的返回值使用yield语句声明而不是return下面就是range()函数版本:

如生成一个斐波拉契数列:

2 装饰器(decorator)装饰器可以在不改变源代码的情况下修改(装饰)已经存在的函数(为已经存在的函数添加功能)如果需要添加原始函数的功能,则必须重写return语句,并且会改变返回值的类型对于已经编写完成的程序,改动一处可能会造成其他相关部分出错。

利用装饰器可以在不必改动原有函数的前提下增加功能,经常被用于事务处理、日志记录、验证权限、调试测试等有需求的场景装饰器实质上是一个函数(内部函数和闭包)它把一个函数作为输入并且返回另外一个函数在装饰器中,通常使用下面这些Python技巧:。

*args和**kwargs闭包作为参数的函数由自定义函数document_it()定义了一个装饰器,会实现如下功能:打印输出函数的名字和参数的值;执行含有参数的函数;打印输出结果;返回修改后的函数;

无论传入document_it()的函数func是什么,装饰器都会返回一个新的函数,其中包含函数document_it()新增加的额外语句实际上,装饰器并不需要执行函数func中的代码,只是在结束前函数document_it()调用函数func以便得到func的返回结果和附加代码的结果。

其实质就是装饰器函数以另一个需要装饰的函数为参数,再由装饰器返回需要装饰的函数(闭包),而不是调用它所以,装饰器返回的是一个函数对象调用装饰器时,只需在原函数定义前用"@"引导装饰器函数即可这种对功能没有影响,却能方便程序员使用的语法称为语法糖(syntactic sugar)。

使用语法糖能够增加程序的可读性、减少代码出错的概率

也可以使用多个装饰器:

附代码1:def generator_even():for i in range(1,11):print(第%d步 % i)yield i*2g = generator_even()print(g.__next__())

print(g.__next__())print(g.__next__())第1步2第2步4第3步6附代码2:def my_range(first = 0, last = 10, step = 1):number = first

while number

print(i)1234附代码3:def fibgen(limit):

f0,f1 = 1,1for n in range(limit):yield f0f0,f1 = f1, f0 + f1print(type(fibgen(10)))for x in fibgen(10):

print(x)11235813213455附代码4:def decorator(f): def new_f(x,y): print(参数1为%d,参数2为%d %(x,y))

return f(x,y) return new_f@ decoratordef add(x,y): return x+yprint(add(5,7))参数1为5,参数2为712附代码5:# 定义装饰器

def document_it(func):def new_func(*args, **kwargs):print(Running function:, func.__name__)print(Positional arguments:, args)

print(Keyword arguments:, kwargs)result = func(*args, **kwargs)print(result, result)return resultreturn new_func

# 1 人工赋值的方式使用装饰器#定义需要装饰的函数def add(a,b):return a + bnewFunc = document_it(add)newFunc(3,5)# 2 直接在要装饰的函数前添加装饰器名字

@document_it#定义需要装饰的函数def add2(a,b):return a + badd2(3,5)上述两种使用装饰器的方式,返回的内容是一样的:Running function: add

Positional arguments: (3, 5)Keyword arguments: {}result 8附代码6:# 使用多个装饰器def square_it(func):def new_func(*args, ** kwargs):

result = func(*args, ** kwargs)return result * resultreturn new_func@document_it@square_it#定义需要装饰的函数def add3(a,b):

return a + badd3(3,5)Running function: new_funcPositional arguments: (3, 5)Keyword arguments: {}result 64

-End-

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

河南中青旅行社综合资讯 奇遇综合资讯 盛世蓟州综合资讯 综合资讯 游戏百科综合资讯 新闻82994