python之yield与装饰器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之yield与装饰器相关的知识,希望对你有一定的参考价值。
防伪码:忘情公子著
python中的yield:
在之前发布的《python之列表解析与生成器》中我们有提到过,生成器所实现的是跟列表解析近似的效果,但是我们不能对生成器做一些属于列表解析的操作。
因为生成器本身就不是一个列表,它只是模拟了一个类似列表的行为,因此,施加在列表中的很多操作,对生成器而言是无效的。
由于生成器表达式并不会直接创建出序列形式的列表,因此不能对其进行索引、切片,不能执行任何常规的列表操作。比如:弹出元素(pop())、添加元素(append())等等。但是我们可以通过list函数将生成器转换成列表。
In [1]: list((i**2 for i in range(1,11))) Out[1]: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
很多情况下我们需要生成更为复杂的结果,又不想基于某个列表来实现,但是简单的使用一个生成器表达式很难实现此种行为。此时我们可以通过一个自定义函数来完全实现类似的效果。
In [2]: def genNum(x): ...: y = 0 ...: while y <= x: ...: yield y ...: y += 1 ...: In [3]: g1 = genNum(10) In [4]: type(g1) Out[4]: generator In [5]: g1.next() Out[5]: 0 In [6]: g1.next() Out[6]: 1 In [7]: g1.next() Out[7]: 2 In [8]: g1.next() Out[8]: 3 In [9]: g1.next() Out[9]: 4 In [10]: g1.next() Out[10]: 5 In [11]: g1.next() Out[11]: 6 In [12]: g1.next() Out[12]: 7 In [13]: g1.next() Out[13]: 8 In [14]: g1.next() Out[14]: 9 In [15]: g1.next() Out[15]: 10 In [16]: g1.next() --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-16-9066a8f18086> in <module>() ----> 1 g1.next() StopIteration:
yield本身并不是一个返回值,却能够生成一个生成器对象。
如上例所看到的,当我们在函数中使用yield,会返回一个生成器对象。
求1到20以内所有正整数的平方:
In [17]: def genNum(n): ...: count = 1 ...: while count <= n: ...: yield count ** 2 ...: count += 1 ...: In [18]: g1 = genNum(20) In [19]: for i in g1: ...: print i ...: 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400
Python中的装饰器:
装饰器即函数装饰器,装饰器自身是一个函数,它的主要目的在于能够把其它函数的功能增强。
装饰器能够实现函数代码重用,或者说函数功能在不同环境中重用。
装饰器是一个非常著名的设计模式,经常用于比如插入日志、性能测试、事务处理等。
装饰器可以抽离出大量的函数中与函数无关的功能,把函数本身只作为一个核心,在必要时如果函数的核心功能不够,就用装饰器装饰一下本次调用所需要的功能,于是运行结束了,下次当需要其它功能时再用装饰器给重新装饰一下就可以了,这就是装饰器。
装饰器需要接受一个函数对象作为其参数,而后对此函数做包装,以对此函数进行增强。
不带参数的func(被装饰的函数):
In [20]: def decorative(func): ...: def wrapper(): #定义一个包装器 ...: print "Please say something: " ...: func() #调用func,这个func是我们自己定义的 ...: print "No zuo no die..." ...: return wrapper ...: In [21]: @decorative #使用@符号调用装饰器 ...: def show(): #定义func,名字取什么都无所谓,它只是用来传给装饰器中的func参数 ...: print "I‘m from Mars." ...: show() ...: Please say something: I‘m from Mars. No zuo no die...
如上例所示,show函数本身只有一个print语句,而使用装饰器以后,就变成了三个print,这里的print可以改成任何其它的语句,这就是函数的装饰器。
带参数的func(被装饰的函数):
In [22]: def decorative(func): ...: def wrapper(x): ...: print "Please say something...>" ...: func(x) ...: print "no zuo no die..." ...: return wrapper ...: In [23]: @decorative ...: def show(x): ...: print x ...: In [24]: show("hello,mars.") Please say something...> hello,mars. no zuo no die...
本文出自 “忘情博” 博客,请务必保留此出处http://itchentao.blog.51cto.com/5168625/1885183
以上是关于python之yield与装饰器的主要内容,如果未能解决你的问题,请参考以下文章