python生成器和装饰器_python之yield与装饰器
防偽碼:忘情公子著
python中的yield:
在之前發(fā)布的《python之列表解析與生成器》中我們有提到過(guò),生成器所實(shí)現(xiàn)的是跟列表解析近似的效果,但是我們不能對(duì)生成器做一些屬于列表解析的操作。
因?yàn)樯善鞅旧砭筒皇且粋€(gè)列表,它只是模擬了一個(gè)類似列表的行為,因此,施加在列表中的很多操作,對(duì)生成器而言是無(wú)效的。
由于生成器表達(dá)式并不會(huì)直接創(chuàng)建出序列形式的列表,因此不能對(duì)其進(jìn)行索引、切片,不能執(zhí)行任何常規(guī)的列表操作。比如:彈出元素(pop())、添加元素(append())等等。但是我們可以通過(guò)list函數(shù)將生成器轉(zhuǎn)換成列表。In?[1]:?list((i**2?for?i?in?range(1,11)))
Out[1]:?[1,?4,?9,?16,?25,?36,?49,?64,?81,?100]
很多情況下我們需要生成更為復(fù)雜的結(jié)果,又不想基于某個(gè)列表來(lái)實(shí)現(xiàn),但是簡(jiǎn)單的使用一個(gè)生成器表達(dá)式很難實(shí)現(xiàn)此種行為。此時(shí)我們可以通過(guò)一個(gè)自定義函數(shù)來(lái)完全實(shí)現(xiàn)類似的效果。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)
?in?()
---->?1?g1.next()
StopIteration:
yield本身并不是一個(gè)返回值,卻能夠生成一個(gè)生成器對(duì)象。
如上例所看到的,當(dāng)我們?cè)诤瘮?shù)中使用yield,會(huì)返回一個(gè)生成器對(duì)象。
求1到20以內(nèi)所有正整數(shù)的平方: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中的裝飾器:
裝飾器即函數(shù)裝飾器,裝飾器自身是一個(gè)函數(shù),它的主要目的在于能夠把其它函數(shù)的功能增強(qiáng)。
裝飾器能夠?qū)崿F(xiàn)函數(shù)代碼重用,或者說(shuō)函數(shù)功能在不同環(huán)境中重用。
裝飾器是一個(gè)非常著名的設(shè)計(jì)模式,經(jīng)常用于比如插入日志、性能測(cè)試、事務(wù)處理等。
裝飾器可以抽離出大量的函數(shù)中與函數(shù)無(wú)關(guān)的功能,把函數(shù)本身只作為一個(gè)核心,在必要時(shí)如果函數(shù)的核心功能不夠,就用裝飾器裝飾一下本次調(diào)用所需要的功能,于是運(yùn)行結(jié)束了,下次當(dāng)需要其它功能時(shí)再用裝飾器給重新裝飾一下就可以了,這就是裝飾器。
裝飾器需要接受一個(gè)函數(shù)對(duì)象作為其參數(shù),而后對(duì)此函數(shù)做包裝,以對(duì)此函數(shù)進(jìn)行增強(qiáng)。
不帶參數(shù)的func(被裝飾的函數(shù)):In?[20]:?def?decorative(func):
...:?????def?wrapper():????#定義一個(gè)包裝器
...:?????????print?"Please?say?something:?"
...:?????????func()????#調(diào)用func,這個(gè)func是我們自己定義的
...:?????????print?"No?zuo?no?die..."
...:?????return?wrapper
...:
In?[21]:?@decorative????#使用@符號(hào)調(diào)用裝飾器
...:?def?show():????#定義func,名字取什么都無(wú)所謂,它只是用來(lái)傳給裝飾器中的func參數(shù)
...:?????print?"I‘m?from?Mars."
...:?show()
...:
Please?say?something:
I‘m?from?Mars.
No?zuo?no?die...
如上例所示,show函數(shù)本身只有一個(gè)print語(yǔ)句,而使用裝飾器以后,就變成了三個(gè)print,這里的print可以改成任何其它的語(yǔ)句,這就是函數(shù)的裝飾器。
帶參數(shù)的func(被裝飾的函數(shù)):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...
總結(jié)
以上是生活随笔為你收集整理的python生成器和装饰器_python之yield与装饰器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python相同key合并value_p
- 下一篇: python 监视图_python获取z