Was genau bedeutet "durchsuchbar" bedeutet in Python?
Zuerst möchte ich klarstellen, ich bin NICHT zu Fragen, was ist "iterator".
Dies ist, wie der Begriff "durchsuchbar" ist in Python definiert ist doc:
iterierbar
Ein Objekt in der Lage die Rückkehr seiner Mitglieder ein zu einer Zeit.
Beispiele von iterables gehören alle Sequenz-Typen (wie list, str,
und Tupel) und einige nicht-Sequenz-Typen wie dict, file-Objekten, und
Objekte von Klassen, die Sie definieren, mit einem __iter__ (), __getitem__()
Methode. Iterables können verwendet werden in einer for-Schleife und in vielen anderen Orten
wo eine Sequenz benötigt wird (zip(), map(), ...). Wenn ein durchsuchbar
Objekt als argument übergeben, um die eingebaute Funktion iter(),
gibt einen iterator für das Objekt. Dieser iterator ist gut für einen Durchgang
über der Menge der Werte. Bei der Verwendung von iterables, es ist in der Regel nicht
notwendig zum Aufruf von iter() oder befassen sich mit iterator-Objekte zu erstellen. Die
for-Anweisung macht das automatisch für Sie, Sie erstellen eine temporäre
Unbenannte variable, um den iterator für die Dauer der Schleife.
Siehe auch iterator, sequence und einem generator.
Als andere Personen vorgeschlagen, mit isinstance(e, collections.Iterable)
ist die pythonic Weg, um zu überprüfen, ob ein Objekt ist iterierbar.
So habe ich einige test mit Python 3.4.3:
from collections.abc import Iterable
class MyTrain:
def __getitem__(self, index):
if index > 3:
raise IndexError("that's enough!")
return index
for name in MyTrain():
print(name) # 0, 1, 2, 3
print(isinstance(MyTrain(), Iterable)) # False
Das Ergebnis ist schon Recht seltsam: MyTrain
definiert hat __getitem__
Methode, aber es ist als nicht wiederholenden Objekt, nicht zu erwähnen, es ist in der Lage, die Rückkehr einer Zahl zu einem Zeitpunkt.
Dann entfernte ich __getitem__
und fügte hinzu, die __iter__
Methode:
from collections.abc import Iterable
class MyTrain:
def __iter__(self):
print("__iter__ called")
pass
print(isinstance(MyTrain(), Iterable)) # True
for name in MyTrain():
print(name) # TypeError: iter() returned non-iterator of type 'NoneType'
Es ist jetzt als eine "wahre" wiederholenden Objekt, obwohl es nicht etwas zu produzieren, während der Iteration.
Also habe ich etwas missverstehen oder ist die Doku falsch?
isinstance
nicht überprüfen, dass die Schnittstelle ordnungsgemäß umgesetzt werden, dass nicht zu bekommen, fand heraus, bis Sie tatsächlich versuchen, zu Durchlaufen, nur, dass die entsprechende Methode(N) (in diesem Fall nur __iter__
) verfügbar sind.docs.python.org/3/library/...
"mit
isinstance(e, collections.Iterable)
ist die pythonic Weg, um zu überprüfen, ob ein Objekt ist iterierbar" - Nein, ich würde sagen, dass Sie versuchen zu Durchlaufen, es ist die Pythonic way!um zu testen, ob etwas ist ein iterierbar, ich mache ein try / außer block in dem ich versuche var = iter(var), wenn er wirft, und der Ausnahme -, dann ist es nicht iterierbar
Aber das wäre kontraproduktiv, denn es könnte zu verbrauchen, das iterierbar ist. Vielleicht ist ein besserer check wäre, zu versuchen
iter(x)
und sehen, ob es wirft ein TypeError
.InformationsquelleAutor laike9m | 2015-09-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, der Punkt der Verwirrung ist hier, dass, obwohl die Umsetzung
__getitem__
hat erlauben, Sie zu iterieren über ein Objekt, es ist nicht Teil der Schnittstelle definiert durchDurchsuchbar
.Den abstrakte Basisklassen ermöglichen eine form der virtuellen Unterklassen, in denen Klassen, die die Implementierung der angegebenen Methoden (im Fall von
Iterable
nur__iter__
) alsisinstance
undissubclass
werden Unterklassen der ABC , auch wenn Sie nicht explizit von der Sie Erben. Es überprüft nicht, ob die Implementierung der Methode tatsächlich funktioniert, obwohl, nur ob oder nicht es zur Verfügung gestellt.Weitere Informationen finden Sie unter PEP-3119, die eingeführt ABC.
Ich bin nicht einverstanden; ich würde duck-typing und nur Versuch Durchlaufen Sie das Objekt. Wenn das Objekt ist nicht durchsuchbar eine
TypeError
angehoben werden, was können Sie fangen in Ihrer Funktion, wenn Sie wollen deal mit nicht-wiederholenden-Eingänge, oder erlauben, zu versickern bis auf den Anrufer, wenn nicht. Diese völlig side-Schritte, wie das Objekt hat beschlossen, die iteration, und findet Sie einfach aus, ob oder ob nicht es ist die am besten geeignete Zeit.Hinzufügen von ein wenig mehr, ich denke die docs haben Sie zitiert sind leicht irreführend. Zitat der
iter
docs, die vielleicht klar, dass dies bis:Dies macht es klar, dass, obwohl beide Protokolle machen das Objekt iterierbar, nur ist die eigentliche "iteration Protokoll", und es ist diese, dass
isinstance(thing, Iterable)
tests für. Deshalb konnten wir feststellen, dass eine Möglichkeit zu prüfen, für "Dinge, die Sie Durchlaufen" im allgemeinsten Fall wäre:obwohl dies auch funktioniert, benötigen Sie zur Umsetzung
__len__
zusammen mit__getitem__
zu "quasi sub-Klasse"Sequence
.collections.abc.Iterable
darstellt gültig iteration container(ich habe dieses Wort), damit ist jedes Objekt, das definiert, der__iter__
Methode.So
collections.abc.Iterable
ist nicht unbedingt "iterierbar" da könnte es die Rückkehr eines ungültigen iterator, die nicht implementiert__next__
. Inzwischen werden auch "durchsuchbar" Objekt konnte keine Beziehung mitcollections.abc.Iterable
nur durch die Definition__getitem__
. Was denkst du?das ist richtig, aber dann einfach die Definition einer
__getitem__
Methode ist auch keine Garantie, dass es tatsächlich Werke! Dies ist der Grund, warum ich lieber die duck typing "EAFP" Ansatz - da kann man nicht wirklich wissen, ob ein Objekt ist das tatsächlich durchsuchbar, bis Sie es tun, dann ist das die geeignete Zeit, um mit Ihr umzugehen, nicht. Idealerweise sollte die Dokumentation etwas sagen wie "ein Objekt ist iterierbar, wenn es implementiert die iterator-oder Sequenz-Protokolle", vielleicht, obwohl es scheint, dass__len__
ist es nicht notwendig, in der Praxis.InformationsquelleAutor jonrsharpe
Es ist ein durchsuchbar. Allerdings haben Sie nicht geerbt von
abc.Iterable
, so natürlich ist Python nicht melden Sie es als Abstieg aus dieser Klasse. Die zwei Dinge -ein iterierbar und Abstieg aus, dass die Basis-Klasse - sind ziemlich getrennt.__iter__
sind virtuelle Unterklassen vonIterable
auch wenn Sie nicht explizit Erben.InformationsquelleAutor Daniel Roseman
Iterable
ist etwas(Sammel alles), das es ermöglicht eine Art der iteration über die Elemente. Aber was ist der generische Weg der iteration in python? Das ist mit -in
Schlüsselwort, das verwendet__iter__
Methode eines Objekts. Also, in Bezug auf jedes Objekt, das definiert__iter__
können verwendet werdenin
und ist Durchsuchbar.So, die meisten "duck-typish' Weg, um zu überprüfen, ob ein Objekt ist iterierbar ist, wenn ein Objekt (Ja, ich weiß implizit, dass ist es, was geschieht in
isinstance
Fall durch virtuelle Klassen)weil nach duck-typing, wir kümmern uns um das Verhalten von einem Objekt, anstatt Ihre ancestory.
Wenn Sie haben eine fehlerhafte Implementierung von
__iter__
dass bedeutet nicht, dass Objekt ist nicht durchsuchbar, es bedeutet nur, dass Sie Fehler in Ihrem code.Hinweis:- Diese Objekte, die definieren nicht
__iter__
noch durchsuchbar im Allgemeinen Sinne, durch die Verwendung einer anderen Methode, es ist nur Sie kann nicht mitin
Schlüsselwort.E. g.:-
NumberList
Instanz ist durchsuchbar übereach
Methode, ist aber nicht durchsuchbar in python Sinn.hasattr(train, '__iter__')
ist ungefähr das, wasisinstance(train, Iterable)
bereits tut.Ich weiß, aber das ist etwas irreführend. Glaubst du nicht, isinstance sollten überprüfen, Vererbung statt
Wenn ein Objekt 'iter' Methode, es ist uns egal, ob es die Instanz von Durchsuchbar oder nicht. Nicht, dass das, was duck typing bedeutet
"Sie glaube nicht, dass isinstance sollten überprüfen, Vererbung anstelle" - Nein, ich denke, es sollte das tun, was es ist dokumentiert auf: "true" Zurück, wenn das Objekt-argument ist eine Instanz der classinfo argument oder eine (direkte, indirekte oder virtuelle) Unterklasse davon." (wobei für virtuelle finden Sie unter docs.python.org/3/glossary.html#term-abstract-base-class)
Duck-typing bedeutet nicht mit
hasattr
überhaupt, nur schriftlichfor thing in train:
und entweder den Umgang mit dem Fehler in der Funktion oder der Vermietung der Anrufer fangen.InformationsquelleAutor hspandher