小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Python基礎(chǔ)篇--迭代器,生成器和裝飾器

 老三的休閑書(shū)屋 2020-12-29

迭代

遵循迭代器協(xié)議時(shí),需要Python迭代器對(duì)象支持兩種方法。

__iter__返回迭代器對(duì)象本身。這用于forin語(yǔ)句。

__next__方法從迭代器返回下一個(gè)值。如果沒(méi)有其他項(xiàng)目要返回,則應(yīng)引發(fā)StopIteration異常。

class Counter(object): def __init__(self, low, high): self.current = low self.high = high def __iter__(self): 'Returns itself as an iterator object' return self def __next__(self): 'Returns the next value till current is lower than high' if self.current > self.high: raise StopIteration else: self.current += 1 return self.current - 1

現(xiàn)在,我們可以在代碼中使用此迭代器。

>>> c = Counter(5,10)>>> for i in c:...   print(i, end=' ')...5 6 7 8 9 10

請(qǐng)記住,迭代器對(duì)象只能使用一次。這意味著在它 一次引發(fā)StopIteration之后,它將繼續(xù)引發(fā)相同的異常。

>>> c = Counter(5,6)>>> next(c)5>>> next(c)6>>> next(c)Traceback (most recent call last):File '<stdin>', line 1, in <module>File '<stdin>', line 11, in nextStopIteration>>> next(c)Traceback (most recent call last):File '<stdin>', line 1, in <module>File '<stdin>', line 11, in nextStopIteration

在前面看到的for循環(huán)示例中使用迭代器,以下示例嘗試在后臺(tái)顯示代碼。

>>> iterator = iter(c)>>> while True:...     try:...         x = iterator.__next__()...         print(x, end=' ')...     except StopIteration as e:...         break...5 6 7 8 9 10

發(fā)電機(jī)

在本節(jié)中,我們將學(xué)習(xí)Python生成器。它們是在Python 2.3中引入的。這是一種使用函數(shù)的關(guān)鍵字yield創(chuàng)建迭代器的簡(jiǎn)便方法。

>>> def my_generator():... print('Inside my generator')... yield 'a'... yield 'b'... yield 'c'...>>> my_generator()<generator object my_generator at 0x7fbcfa0a6aa0>

在上面的示例中,我們使用yield語(yǔ)句創(chuàng)建了一個(gè)簡(jiǎn)單的生成器。就像使用其他迭代器一樣,我們可以在for循環(huán)中使用它。

>>> for char in my_generator():...     print(char)...Inside my generatorabc

在下一個(gè)示例中,我們將使用生成器函數(shù)創(chuàng)建相同的Counter類,并將其用于for循環(huán)中。

def counter_generator(low, high): while low <= high: yield low low += 1 >>> for i in counter_generator(5,10):... print(i, end=' ')...5 6 7 8 9 10

在while循環(huán)中,當(dāng)?shù)竭_(dá)yield語(yǔ)句時(shí),將返回low的值,并暫停生成器狀態(tài)。在第二個(gè)下一個(gè)調(diào)用期間,生成器恢復(fù)到之前凍結(jié)的位置,然后將low的值增加1。它繼續(xù)while循環(huán),并再次返回yield語(yǔ)句。

調(diào)用生成器函數(shù)時(shí),它將返回* generator *對(duì)象。如果在此對(duì)象上調(diào)用* dir *,您會(huì)發(fā)現(xiàn)它包含__iter__和* __ next __ *方法以及其他方法。

   >>> c = counter_generator(5,10)   >>> dir(c)   ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__','__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__','__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__reduce__','__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__','close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw']

如果大家在學(xué)習(xí)中遇到困難,想找一個(gè)python學(xué)習(xí)交流環(huán)境,可以加入我們的python裙,關(guān)注小編,并私信“01”即可進(jìn)裙,領(lǐng)取python學(xué)習(xí)資料,會(huì)節(jié)約很多時(shí)間,減少很多遇到的難題。


我們主要使用生成器進(jìn)行延遲評(píng)估。這樣,生成器就成為處理大量數(shù)據(jù)的好方法。如果您不想將所有數(shù)據(jù)加載到內(nèi)存中,則可以使用生成器,該生成器將一次向您傳遞每個(gè)數(shù)據(jù)。

該示例的最大示例之一是os.path.walk()函數(shù),該函數(shù)使用回調(diào)函數(shù)和當(dāng)前的os.walk生成器。使用生成器實(shí)現(xiàn)可節(jié)省內(nèi)存。

我們可以有生成無(wú)限值的生成器。以下是一個(gè)這樣的示例。

>>> def infinite_generator(start=0):... while True:... yield start... start += 1...>>> for num in infinite_generator(4):... print(num, end=' ')... if num > 20:... break...4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

如果我們回到my_generator的示例,我們將發(fā)現(xiàn)生成器的一項(xiàng)功能。它們不可重復(fù)使用。

>>> g = my_generator()>>> for c in g:...     print(c)...Inside my generatorabc>>> for c in g:...     print(c)...

創(chuàng)建可重用生成器的一種方法是不持有任何狀態(tài)的基于對(duì)象的生成器。任何具有__iter__方法的類都可以產(chǎn)生數(shù)據(jù),可以用作對(duì)象生成器。在下面的示例中,我們將重新創(chuàng)建計(jì)數(shù)器生成器。

>>> class Counter(object):... def __init__(self, low, high):... self.low = low... self.high = high... def __iter__(self):... counter = self.low... while self.high >= counter:... yield counter... counter += 1...>>> gobj = Counter(5, 10)>>> for num in gobj:... print(num, end=' ')...5 6 7 8 9 10>>> for num in gobj:... print(num, end=' ')...5 6 7 8 9 10

生成器表達(dá)式

在本節(jié)中,我們將學(xué)習(xí)生成器表達(dá)式,它是列表理解和生成器的高性能,內(nèi)存高效的概括。

例如,我們將嘗試對(duì)1到9之間所有數(shù)字的平方求和。

>>> sum([x*x for x in range(1,10)])

該示例實(shí)際上首先在內(nèi)存中創(chuàng)建一個(gè)平方值列表,然后對(duì)其進(jìn)行迭代,最后在求和后釋放內(nèi)存。如果列表很大,您可以了解內(nèi)存使用情況。

我們可以使用生成器表達(dá)式來(lái)節(jié)省內(nèi)存使用量。

sum(x*x for x in range(1,10))

生成器表達(dá)式的語(yǔ)法表明,始終必須直接在一組括號(hào)內(nèi),并且兩邊都不能有逗號(hào)。這基本上意味著以下兩個(gè)示例都是有效的生成器表達(dá)式用法示例。

>>> sum(x*x for x in range(1,10))285>>> g = (x*x for x in range(1,10))>>> g<generator object <genexpr> at 0x7fc559516b90>

我們可以鏈接生成器或生成器表達(dá)式。在以下示例中,我們將讀取文件* / var / log / cron *,并將查找是否有任何特定作業(yè)(在示例中,我們正在搜索anacron)是否成功運(yùn)行。

我們可以使用shell命令tail -f / var / log / cron | grep anacron進(jìn)行相同的操作

>>> jobtext = 'anacron'>>> all_lines = (line for line in open('/var/log/cron', 'r') )>>> job = ( line for line in all_lines if line.find(jobtext) != -1)>>> text = next(job)>>> text'May 6 12:17:15 dhcp193-104 anacron[23052]: Job `cron.daily' terminated\n'>>> text = next(job)>>> text'May 6 12:17:15 dhcp193-104 anacron[23052]: Normal exit (1 job run)\n'>>> text = next(job)>>> text'May 6 13:01:01 dhcp193-104 run-parts(/etc/cron.hourly)[25907]: starting 0anacron\n'

您可以在各行中編寫(xiě)一個(gè)for循環(huán)。


閉包

閉包不過(guò)是由另一個(gè)函數(shù)返回的函數(shù)。我們使用閉包刪除代碼重復(fù)。在下面的示例中,我們創(chuàng)建一個(gè)簡(jiǎn)單的閉包以添加數(shù)字。

>>> def add_number(num):...     def adder(number):...         'adder is a closure'...         return num + number...     return adder...>>> a_10 = add_number(10)>>> a_10(21)31>>> a_10(34)44>>> a_5 = add_number(5)>>> a_5(3)8

加法器是一種閉包,它將給定的數(shù)字添加到預(yù)定義的數(shù)字中。

裝飾器

裝飾器是一種向某些對(duì)象動(dòng)態(tài)添加一些新行為的方法。我們通過(guò)使用閉包在Python中實(shí)現(xiàn)了相同的目的。

在該示例中,我們將創(chuàng)建一個(gè)簡(jiǎn)單的示例,該示例將在函數(shù)執(zhí)行前后打印一些語(yǔ)句。

>>> def my_decorator(func):... def wrapper(*args, **kwargs):... print('Before call')... result = func(*args, **kwargs)... print('After call')... return result... return wrapper...>>> @my_decorator... def add(a, b):... 'Our add function'... return a + b...>>> add(1, 3)Before callAfter call4


最后多說(shuō)一句,小編是一名python開(kāi)發(fā)工程師,這里有我自己整理的整套python學(xué)習(xí)資料和路線,想要這些資料的都可以關(guān)注小編,并私信“01”領(lǐng)取。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多