Pythonのiterableオブジェクトの理解方法
4797 ワード
転載は出典を明記してください.https://www.jianshu.com/u/5e6f798c903a[^*]は脚注を表し、文末では対応する接続を表示できますが、この構文はサポートされていません.
まず,コンテナとiterableの間には必然的な関連性はない.オブジェクトは、iterable以外のコンテナであってもよいし、非コンテナのiterable(ファイルオブジェクトやソケットオブジェクトなど)であってもよい.さらに、コンテナは通常有限であり、iterableは無限のデータソースを表すことができる.コンテナについては、Pythonのコンテナオブジェクトの理解方法について別の記事を参照してください.
iterableは、公式ドキュメントの文脈に次の2つの意味があります.1つ目は特に実現した 2つ目はiterableを抽象概念とする.内蔵関数
1.iterableとforループ
iterableを
出力:
出力を観察することにより、可視解釈器が明示的に
2.iterableと内蔵関数
iterableは、組み込み関数など、順序オブジェクトが必要な場所でも使用できます. ....
内蔵関数としては、iterableパラメータに第2の意味が用いられており、厳密な意味ではない
たとえば、文書に組み込まれている関数
反復可能(iterable)オブジェクトの要素のブール値が
これにより,内蔵関数にiterableパラメータがある場合,iterableを反復器に変換してから処理することが推測される.内蔵関数の内部では
3.IterableObjcと_iter__
まず2つの概念を明確にします.IterableObjc:すべて実現 反復器:同時実現
本質的には
脚注:[1]:言語参照-3.1.Objects,values and types[2]:標準ライブラリ8.4.
まず,コンテナとiterableの間には必然的な関連性はない.オブジェクトは、iterable以外のコンテナであってもよいし、非コンテナのiterable(ファイルオブジェクトやソケットオブジェクトなど)であってもよい.さらに、コンテナは通常有限であり、iterableは無限のデータソースを表すことができる.コンテナについては、Pythonのコンテナオブジェクトの理解方法について別の記事を参照してください.
iterableは、公式ドキュメントの文脈に次の2つの意味があります.
__iter__
メソッドのオブジェクトを指す[^2].本節以降ではそのようなオブジェクトをIterableObjcと呼ぶ.Tips:Iterator
およびGenerator
ともにIterableObjcに属する.from collections import abc
class IterableObjc:
def __iter__(self):
cont = 0
while cont < 3:
cont += 1
yield cont
a_iterable = IterableObjc()
assert isinstance(a_iterable, abc.Iterable) #
iter()
[^5]が許容できる対象であれば、iterableとみなされる(ここでは特にiter()
の単一パラメータ形式を指し、第2パラメータは含まない).したがって、__iter__()
または__getitem__()
のいずれかを定義すれば、iterableとして認定される.ただし、__getitem__()
のオブジェクトのみが定義されており、IterableObjcではない.2番目の意味に含まれるオブジェクトの範囲は、1番目の意味よりも大きく、IterableObjcはiterableのサブセットであると考えられる.このセクションの後続のセクションで説明するiterableは、2つ目の意味を使用します.class GetitemObjc:
def __getitem__(self, item):
cont = 0
while cont <= item:
cont += 1
if cont >= 5:
raise StopIteration()
return cont
a_getitem = GetitemObjc()
assert isinstance(a_getitem, abc.Iterable) #
1.iterableとforループ
iterableを
for
ループに使用する場合は、自分で呼び出す必要はありませんiter()
反復オブジェクトを自分で処理する必要もありません.for
文は、ループ中に反復器を保存するための一時的な無名変数を自動的に作成します.逆アセンブル(disassemble)により、より直感的に理解できるfor
ループの実行手順、コードは以下の通りである.dis.dis("for _ in iterable: pass")
出力:
1 0 SETUP_LOOP 12 (to 14)
2 LOAD_NAME 0 (iterable)
4 GET_ITER
>> 6 FOR_ITER 4 (to 12)
8 STORE_NAME 1 (_)
10 JUMP_ABSOLUTE 6
>> 12 POP_BLOCK
>> 14 LOAD_CONST 0 (None)
16 RETURN_VALUE
出力を観察することにより、可視解釈器が明示的に
GET_ITER
を呼び出し、これは呼び出したiter(iterable)
に相当する.つまりfor
文は自動的に呼び出されるiter(iterable)
となり、iterable
オブジェクトを1つの反復器に変換することになる[^6].FOR_ITER
命令(next()
メソッドに相当)で次の要素を取得できるようにする.注:解釈器が最適化されているため、バイトコード命令からすべてのプロセスを直接観察することはできません.2.iterableと内蔵関数
iterableは、組み込み関数など、順序オブジェクトが必要な場所でも使用できます.
any(iterable)
class list([iterable])
map(function, iterable, ...)
内蔵関数としては、iterableパラメータに第2の意味が用いられており、厳密な意味ではない
IterableObjc
.たとえば、文書に組み込まれている関数
any(iterable)
については、以下のように解釈します.反復可能(iterable)オブジェクトの要素のブール値が
True
の場合、True
が返されます.反復可能オブジェクトが空の場合は、False
を返します.次のコードに相当します.def any(iterable):
for element in iterable:
if element:
return True
return False
これにより,内蔵関数にiterableパラメータがある場合,iterableを反復器に変換してから処理することが推測される.内蔵関数の内部では
for
間接変換をループしてもよいし、直接使用してもよいiter()
変換を行う(ただし、内蔵関数はCで実現されているが、ここでは1つの考え方を与えるためにのみ)3.IterableObjcと_iter__
まず2つの概念を明確にします.
__iter__
の対象はIterableObjcと呼ぶことができる__iter__
および__next__
の対象であり、反復器もIterableObjcに属する.本質的には
__iter__
メソッドは反復器を返すために存在し、容器に反復器を提供する必要がある場合に呼び出される.しかし、IterableObjc自体も反復器である可能性があるため、次の2つのケースが発生します.# :IterableObjc
class IterableObjc:
"""
, __iter__ ,
id , 。
"""
def __iter__(self):
""" , """
cont = 0
while cont < 3:
cont += 1
yield cont
# :IterableObjc
class IteratorObjc:
"""
, __iter__ ,
, id 。
"""
def __iter__(self):
self._count = 0
#
return self
def __next__(self):
while self._count < 3:
self._count += 1
return self._count
脚注:[1]:言語参照-3.1.Objects,values and types[2]:標準ライブラリ8.4.
collections.abc
—Abstract Base Classes for Containers[3]:Iterables vs.Iterators vs.Generators|Python反復オブジェクト、反復器、ジェネレータを完全に理解する[4]:Glossary用語表[5]:iter(object[,sentinel])[6:言語参照-8.3.Thefor
statement[7]:標準ライブラリ-Iterator Type[8]:言語参照-3.3.3.7.Emulating container types