Python筆記:迭代器户辱、生成器鸵钝、修飾器

迭代器(iterators)

迭代器有一個(gè)特點(diǎn),就是每次迭代容器里的一個(gè)數(shù)庐镐,把容器里的數(shù)迭代完之后就會(huì)停止迭代恩商,出現(xiàn) StopIteration
異常”啬妫可以把迭代器理解為洗發(fā)水痕届,每次擠一點(diǎn),擠完了就剩下個(gè)空瓶末患,可以丟掉了研叫。使用容器內(nèi)置函數(shù)__iter__()可以直接生成迭代器,使用iter()函數(shù)也可以生成迭代器璧针。

>>> nums = [1, 2, 3]      
>>> iter(nums)                           
<...iterator object at ...>
#生成一個(gè)迭代器
>>> it = iter(nums)
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

用在for循環(huán)里面:

>>>nums=[1,10,100]
>>>it = nums.__iter__()
>>>sum=0
>>>for i in it:
...:  sum=sum+i
...:print sum
111
>>>for i in it:
...:  sum=sum+i
...:print sum
0

生成器(generators)

生成器通常由推導(dǎo)式生成嚷炉,例如:

>>> (i for i in nums)                    
<generator object <genexpr> at 0x...>
>>> list(i for i in nums)
[1, 2, 3]

如果加上中括號(hào)就是列表、加上中括號(hào)就是字典或者集合:

>>> [i for i in nums]
[1, 2, 3]
>>> {i for i in range(3)}  
set([0, 1, 2])
>>> {i:i**2 for i in range(3)}   
{0: 0, 1: 1, 2: 4}

還有另外一種生成器的表達(dá)方式是yield探橱,當(dāng)next()被調(diào)用時(shí)申屹,就會(huì)執(zhí)行第一個(gè)yield绘证。執(zhí)行完yield語句后,就會(huì)停止哗讥∪履牵看兩個(gè)例子就可以理解:

>>> def f():
...   yield 1
...   yield 2
>>> f()                                   
<generator object f at 0x...>
>>> gen = f()
>>> next(gen)
1
>>> next(gen)
2
>>> next(gen)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration
>>> def f():
...   print("-- start --")
...   yield 3
...   print("-- middle --")
...   yield 4
...   print("-- finished --")
>>> gen = f()
>>> next(gen)
-- start --
3
>>> next(gen)
-- middle --
4
>>> next(gen)                            
-- finished --
Traceback (most recent call last):
 ...
StopIteration

裝飾器(decorators)

假如我們想修正(修飾)一個(gè)已經(jīng)寫好的模塊,又不讓這個(gè)裝飾侵入到原有的模塊代碼中去杆煞,這時(shí)候就需要用到裝飾器啦魏宽。
第一種方法,我們需要寫一個(gè)用來裝飾已有模塊的裝飾函數(shù):

>>> def simple_decorator(function):
...   print("doing decoration")
...   return function

假如我們想修飾function()這個(gè)函數(shù)决乎,只需在函數(shù)上面加上@修飾器:

>>> @simple_decorator
... def function():
...   print("inside function")
doing decoration
>>> function()
inside function

這個(gè)實(shí)際的效果相當(dāng)于:

function = simple_decorator(function) 

將要進(jìn)行修飾的函數(shù)function當(dāng)作參數(shù)傳遞到修飾器simple_decorator中队询,然后在進(jìn)行回調(diào),賦值回原來的function.

我們的修飾器也可以加參數(shù):

>>> def decorator_with_arguments(arg):
...   print("defining the decorator")
...   def _decorator(function):
...       print("doing decoration, %r" % arg)
...       return function
...   return _decorator
>>> @decorator_with_arguments("abc")
... def function():
...   print("inside function")
defining the decorator
doing decoration, 'abc'
>>> function()
inside function

實(shí)際上相當(dāng)于:

function = decorator_with_arguments("abc")(function)

那么實(shí)際上decorator_with_arguments("abc")需要返回一個(gè)真正的修飾器來修飾function构诚。例子中是返回_decorator這個(gè)修飾器蚌斩。

當(dāng)含有多個(gè)修飾器時(shí),修飾順序是從下向上的:

>>> @decorator_one
... @decorator_two
... def func():
...   pass

就相當(dāng)于:

func = decorator_one(decorator_two(func))

第二種方法范嘱,使用類的方法來修飾函數(shù):

>>> class myDecorator(object):
...   def __init__(self, fn):
...     print "inside myDecorator.__init__()"
...     self.fn = fn
... 
...   def __call__(self):
...     self.fn()
...     print "inside myDecorator.__call__()"
...
>>> @myDecorator
... def aFunction():
...   print "inside aFunction()"
...
print "Finished decorating aFunction()"

>>>aFunction()
... inside myDecorator.__init__()
... Finished decorating aFunction()
... inside aFunction()
... inside myDecorator.__call__()

使用類的修飾器會(huì)有兩個(gè)成員:
一個(gè)是__init__()送膳,這個(gè)方法是在我們給某個(gè)函數(shù)修飾時(shí)被調(diào)用。
一個(gè)是__call__()丑蛤,這個(gè)方法是在我們調(diào)用被修飾函數(shù)時(shí)被調(diào)用的肠缨。

Ref:
http://www.scipy-lectures.org/advanced/advanced_python/index.html#decorators
http://coolshell.cn/articles/11265.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市盏阶,隨后出現(xiàn)的幾起案子晒奕,更是在濱河造成了極大的恐慌,老刑警劉巖名斟,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脑慧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡砰盐,警方通過查閱死者的電腦和手機(jī)闷袒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岩梳,“玉大人囊骤,你說我怎么就攤上這事〖街担” “怎么了也物?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長列疗。 經(jīng)常有香客問我滑蚯,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任告材,我火速辦了婚禮坤次,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘斥赋。我一直安慰自己缰猴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布疤剑。 她就那樣靜靜地躺著滑绒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骚露。 梳的紋絲不亂的頭發(fā)上蹬挤,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天缚窿,我揣著相機(jī)與錄音棘幸,去河邊找鬼。 笑死倦零,一個(gè)胖子當(dāng)著我的面吹牛误续,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扫茅,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蹋嵌,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了葫隙?” 一聲冷哼從身側(cè)響起栽烂,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎恋脚,沒想到半個(gè)月后腺办,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡糟描,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年怀喉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片船响。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡躬拢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出见间,到底是詐尸還是另有隱情聊闯,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布米诉,位于F島的核電站馅袁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏荒辕。R本人自食惡果不足惜汗销,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一犹褒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弛针,春花似錦叠骑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至茧跋,卻和暖如春慰丛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瘾杭。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工诅病, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粥烁。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓贤笆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讨阻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子芥永,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容