[轉載] 【python魔術方法】迭代器(__iter__和__next__)

參考鏈接: Python __iter __()和__next __()| 將對象轉換為迭代器

文章目錄

?`__iter__` 和 `__next__`真正的迭代器總結

?

?

?

python里面有很多的以__開始和結尾的函數,利用它們可以完成很多復雜的邏輯代碼,而且提高了代碼的簡潔性,本文主要總結了迭代器用到的魔術方法,并且主要以代碼例子進行解釋。?

__iter__ 和 __next__?

其實這里需要引入一個概念,叫迭代器,常見的就是我們在使用for語句的時候,python內部其實是把for后面的對象上使用了內建函數iter,比如:?

a = [1, 2, 3]

for i in a:

? ? do_something()

?

其實在python內部進行了類似如下的轉換:?

a = [1, 2, 3]

for i in iter(a):

? ? do_something()

?

那么iter返回的是什么呢,就是一個迭代對象,它主要映射到了類里面的__iter__函數,此函數返回的是一個實現了__next__的對象。注意理解這句話,比如:?

class B(object):

? ? def __next__(self):

? ? ? ? raise StopIteration

?

class A(object):

? ? def __iter__(self):

? ? ? ? return B()

?

我們可以看見,A這個類實現了一個__iter__函數,返回的是B()的實例對象,其中B里面實現了__next__這個函數。?

下面引入幾個概念: Iterable: 有迭代能力的對象,一個類,實現了__iter__,那么就認為它有迭代能力,通常此函數必須返回一個實現了__next__的對象,如果自己實現了,你可以返回self,當然這個返回值不是必須的; Iterator: 迭代器(當然也是Iterable),同時實現了__iter__和__next__的對象,缺少任何一個都不算是Iterator,比如上面例子中,A()可以是一個Iterable,但是A()和B()都不能算是和Iterator,因為A只實現了__iter__,而B只實現了__next__()。?

我們可以使用collections里面的類型來進行驗證:?

class B(object):

? ? def __next__(self):

? ? ? ? raise StopIteration

?

class A(object):

? ? def __iter__(self):

? ? ? ? return B()

?

?

from collections.abc import *

?

a = A()

b = B()

print(isinstance(a, Iterable))

print(isinstance(a, Iterator))

?

print(isinstance(b, Iterable))

print(isinstance(b, Iterator))

?

結果是:?

True

False

False

False

?

讓我們稍微對B這個類做一點修改:?

class B(object):

? ? def __next__(self):

? ? ? ? raise StopIteration

?

? ? def __iter__(self):

? ? ? ? return None

?

class A(object):

? ? def __iter__(self):

? ? ? ? return B()

?

?

from collections.abc import *

?

a = A()

b = B()

print(isinstance(a, Iterable))

print(isinstance(a, Iterator))

?

print(isinstance(b, Iterable))

print(isinstance(b, Iterator))

?

結果是:?

True

False

True

True

?

真正的迭代器?

上面只是做了幾個演示,這里具體說明一下: 當調用iter函數的時候,生成了一個迭代對象,要求__iter__必須返回一個實現了__next__的對象,我們就可以通過next函數訪問這個對象的下一個元素了,并且在你不想繼續有迭代的情況下拋出一個StopIteration的異常(for語句會捕獲這個異常,并且自動結束for),下面實現了一個自己的類似range函數的功能。?

class MyRange(object):

? ? def __init__(self, end):

? ? ? ? self.start = 0

? ? ? ? self.end = end

?

? ? def __iter__(self):

? ? ? ? return self

?

? ? def __next__(self):

? ? ? ? if self.start < self.end:

? ? ? ? ? ? ret = self.start

? ? ? ? ? ? self.start += 1

? ? ? ? ? ? return ret

? ? ? ? else:

? ? ? ? ? ? raise StopIteration

?

from collections.abc import *

?

a = MyRange(5)

print(isinstance(a, Iterable))

print(isinstance(a, Iterator))

?

for i in a:

? ? print(i)

?

結果是:?

True

True

0

1

2

3

4

?

接下來我們使用next函數模擬一次:?

class MyRange(object):

? ? def __init__(self, end):

? ? ? ? self.start = 0

? ? ? ? self.end = end

?

? ? def __iter__(self):

? ? ? ? return self

?

? ? def __next__(self):

? ? ? ? if self.start < self.end:

? ? ? ? ? ? ret = self.start

? ? ? ? ? ? self.start += 1

? ? ? ? ? ? return ret

? ? ? ? else:

? ? ? ? ? ? raise StopIteration

?

a = MyRange(5)

print(next(a))

print(next(a))

print(next(a))

print(next(a))

print(next(a))

print(next(a)) # 其實到這里已經完成了,我們在運行一次查看異常

?

可以看見一個很明顯的好處是,每次產生的數據,是產生一個用一個,什么意思呢,比如我要遍歷[0, 1, 2, 3.....]一直到10億,如果使用列表的方式,那么是會全部載入內存的,但是如果使用迭代器,可以看見,當用到了(也就是在調用了next)才會產生對應的數字,這樣就可以節約內存了,這是一種懶惰的加載方式。?

總結?

可以使用collection.abs里面的Iterator和Iterable配合isinstance函數來判斷一個對象是否是可迭代的,是否是迭代器對象iter實際是映射到了__iter__函數只要實現了__iter__的對象就是可迭代對象(Iterable),正常情況下,應該返回一個實現了__next__的對象(雖然這個要求不強制),如果自己實現了__next__,當然也可以返回自己同時實現了__iter__和__next__的是迭代器(Iterator),當然也是一個可迭代對象了,其中__next__應該在迭代完成后,拋出一個StopIteration異常for語句會自動處理這個StopIteration異常以便結束for循環?

生成器相關的文檔已經在這里。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540465.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540465.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540465.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Silverlight 異步單元測試

Silverlight 中的很多操作都是異步的&#xff0c;很多情況下要求單元測試也是異步的&#xff0c;但是介紹異步單元測試的文檔很少。通過對 Silverlight Toolkit 中的 Microsoft.Silverlight.Testing 和 Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight 這兩個文件…

網絡拓撲 令牌環網 以太網_以太網連接中網絡拓撲的類型及其框架 以太網技術...

網絡拓撲 令牌環網 以太網A topology explains how physically the network is designed or what is the structure of the network. These designs are both physical and logical. There are many network topologies 4 like Bus, Star, Ring, and Mesh. But only two types …

Wafer晶圓封裝工藝介紹

芯片封裝的目的&#xff08;The purpose of chip packaging&#xff09;: 芯片上的IC管芯被切割以進行管芯間連接&#xff0c;通過引線鍵合連接外部引腳&#xff0c;然后進行成型&#xff0c;以保護電子封裝器件免受環境污染&#xff08;水分、溫度、污染物等&#xff09;&…

[轉載] Python中的解析式和生成器表達式

參考鏈接&#xff1a; Python | 生成器表達式 解析式和生成器表達式 列表解析List Comprehension 語法 [返回值 for 元素 in 可迭代對象 if 條件]使用中括號[],內部是for循環&#xff0c;if條件語句可選&#xff0c;會返回一個新的列表 列表解析試優點 編譯器會優化&…

java 數字字母進位_使用帶有進位的8085微處理器將兩個8位數字相乘

java 數字字母進位Problem statement: 問題陳述&#xff1a; Multiplication of two 8 bits numbers using 8085 microprocessor with carry. 使用帶有進位的8085微處理器將兩個8位數字相乘。 Algorithm: 算法&#xff1a; Load HL pair with initial data using LHLD comma…

[轉載] Python3.0中普通方法、類方法和靜態方法的比較

參考鏈接&#xff1a; Python中的類方法與靜態方法 一、語法區別 剛接觸Python中的面向對象&#xff0c;對于類方法和靜態方法難以區分&#xff0c;通過查找知乎、CSDN論壇&#xff0c;廢了好大的勁思路才逐漸明朗&#xff0c;所以就總結順便分享一下。 首先開始編輯代碼 # 普…

iOS:個人淺談工廠模式

一、什么是工廠方法&#xff1f; 正式的解釋是&#xff1a;在基類中定義創建對象的一個接口&#xff0c;讓子類決定實例化哪個類。工廠方法讓一個類的實例化延遲到子類中進行。工廠方法要解決的問題是對象的創建時機&#xff0c;它提供了一種擴展的策略&#xff0c;很好地符合了…

scanf 輸入十六進制_使用C語言中的scanf()在字符變量中輸入十進制,八進制和十六進制值...

scanf 輸入十六進制Here, we will declare an unsigned char variable and input different formats value like decimal format, octal format and hexadecimal format. 在這里&#xff0c;我們將聲明一個無符號的char變量&#xff0c;并輸入不同格式的值&#xff0c;例如十進…

[轉載] Python中pass的作用

參考鏈接&#xff1a; 如何在Python中編寫空函數&#xff1f;請使用 pass語句 空語句 do nothing保證格式完整保證語義完整 以if語句為例&#xff0c;在c或c/java中&#xff1a; if(true) ; //do nothing else { //do something } 對應于python就要這樣寫&#xff…

wrf 嵌套網格作用_在網格系統中使用響應列,嵌套列和偏移列 引導程序

wrf 嵌套網格作用介紹 (Introduction) In the previous article, we have learnt what is grid and grid system and how it works? Now, we will learn about how Responsive column, Nesting Columns and Offset Columns works and how to use them? If you have any doubt…

[看書筆記]《深入java虛擬機》——java體系結構(二)

java虛擬機的三種含義&#xff1a; - 抽象的規范 - 一個具體的實現 - 一個運行中的虛擬機實例 ---------------------java虛擬機的生命周期&#xff1a; java虛擬機實例的天職就是負責運行一個java程序。 啟動一個java程序&#xff0c;一個虛擬機實例誕生了&#xff1b;程序關閉…

[轉載] 【零基礎學爬蟲】python中的yield詳解

參考鏈接&#xff1a; 什么時候在Python中使用yield而不是return python中的yield功能比較強大&#xff0c;什么意思呢&#xff1f;如果一個函數f內使用了yield關鍵詞&#xff0c;那么該函數就可以這樣使用&#xff1a; for item in f(***): **** 也就是包含yield關鍵詞的函…

全新的membership框架Asp.net Identity(1)——.Net membership的歷史

在Asp.net上&#xff0c;微軟的membershop框架經歷了Asp.net membership到Asp.net simple membership&#xff0c;再到現在的Asp.net Identity. 每一次改變&#xff0c;都使得驗證框架更加的適應變化和可定制。這篇文章是Asp.net Identity系列的開篇&#xff0c;主要就membersh…

c語言100位整數變量聲明_C ++程序動態聲明一個整數變量并打印其內存地址

c語言100位整數變量聲明Here, we will learn how we can declare an integer variable dynamically and how to print address of declared memory block? 在這里&#xff0c;我們將學習如何動態聲明整數變量&#xff0c;以及如何打印聲明的內存塊的地址&#xff1f; In C pr…

[轉載] python 函數返回多個值

參考鏈接&#xff1a; 在Python中返回多個值 &#xff08;廖雪峰Python教程學習筆記&#xff09; 函數體內部的語句在執行時&#xff0c;一旦執行到return&#xff0c;函數就執行完畢&#xff0c;并將結果返回。 如果沒有return語句&#xff0c;函數執行完畢后也會返回結果…

二.編寫第一個c#程序(注釋,命名空間,類,Main方法,標識符,關鍵字,輸入,輸出語句,)...

復習編寫一個控制臺應用程序&#xff0c;目標是在控制臺輸出“Hello World” 1.第一步&#xff0c;打開Visual Studio 2012以上版本(我用的是VS 2015)&#xff0c;打開完成后出現以下界面 2.第二步&#xff0c;這時候就要新建一個解決方案了&#xff0c;創建解決方案可以直接點…

[轉載] Python中定義函數,循環語句,條件語句

參考鏈接&#xff1a; Python中的局部函數 由于日常程序流中主要是三種結構&#xff1a;順序&#xff0c;循環&#xff0c;條件&#xff0c;且往往需要自定義函數再調用&#xff0c; 因此今天想學習一下Python中關于定義函數、循環語句和條件語句的寫法。 1.定義函數 區…

node oauth2驗證_如何設置和使用護照OAuth Facebook身份驗證(第1部分)| Node.js

node oauth2驗證In my last articles, we looked at the implementation of the passport-local authentication strategy. We also looked at the various requirements to get started with the login form. 在上一篇文章中&#xff0c;我們介紹了護照本地身份驗證策略的實現…

vue2.0 引用qrcode.js實現獲取改變二維碼的樣式

vue代碼 <template><div class"qart"><div id"qrcode" ref"qrcode"></div><input type"text" id"getval" value"" placeholder"修改這個值改變二維碼"></div> <…

[轉載] Python列表排序 list.sort方法和內置函數sorted

參考鏈接&#xff1a; Python中的函數 Python列表排序 list.sort方法和內置函數sorted 很多時候我們獲取到一個列表后,這個列表并不滿足我們的需求,我們需要的是一個有特殊順序的列表. 這時候就可以使用list.sort方法和內置函數sorted,本文就是介紹list.sort方法和sorted內…