Seite 1 von 1

auf iterierbarkeit prüfen?

Verfasst: Samstag 14. Juli 2007, 21:19
von EnTeQuAk
Ich habe nur mal eine kleine Frage.

Wie kann ich eine Variable auf iterierbarkeit prüfen?

Übersehe ich eine builtin-function oder geht das nur, indem ich auf vorhandensein der methode __iter__ prüfe?

Danke schonmal im Vorraus!


MfG EnTeQuAk

Verfasst: Samstag 14. Juli 2007, 21:54
von rafael
EnTeQuAk hat geschrieben:Übersehe ich eine builtin-function
Jap. ;)

Code: Alles auswählen

def is_iterable(arg):
    try:
        iter(arg)
        return True
    except TypeError:
        return False
Cheers,
Rafael

Verfasst: Sonntag 15. Juli 2007, 09:34
von EnTeQuAk
Dann habe ich mich falsch ausgedrückt.

Ich meinte eher, iterierbare Objekte, wie generator-objekte, Listen, und Tupel.

Mit `iter` kann ich auch ein `str` Objekt iterierbar machen.

Das wollte ich nicht prüfen.

Es geht darum, das in einer Variable etweder nur ein einzelner Wert steht oder eine Liste, ein Tupel oder ein generator-objekt.

Ich möchte herausfinden, ob ein einzelner Wert drinne steht oder eben eine Liste, ein Tupel usw.

So weit, wie ich gesehen habe, gibts da halt die Möglichkeit, über __iter__. Das besitzten nur die Objekte, über die ich auch wirklich iterieren möchte. Also Listen, Tupel usw.


Übersehe ich immernoch etwas?

MfG EnTeQuAk

Verfasst: Sonntag 15. Juli 2007, 09:44
von Leonidas
EnTeQuAk hat geschrieben:Mit `iter` kann ich auch ein `str` Objekt iterierbar machen.
Über ``str``-Objekte kann man auch so schon iterieren, da braucht man kein ``iter()`` dafür.

Verfasst: Sonntag 15. Juli 2007, 09:56
von EnTeQuAk
Über ``str``-Objekte kann man auch so schon iterieren, da braucht man kein ``iter()`` dafür.
Was ja auch für Listen, Tupel, und Generator-Objekte zutrifft.

Das ist ja aber nicht das problem, was ich habe ;)

Verfasst: Sonntag 15. Juli 2007, 11:10
von rafael
Also ein ganzer String über den man normalerweise iterieren kann, soll bei dir auch als einzelner Wert gelten?

Code: Alles auswählen

def is_iterable(arg):
    if type(arg) == str:
        return False
    try:
        iter(arg)
        return True
    except TypeError:
        return False

Verfasst: Sonntag 15. Juli 2007, 11:26
von BlackJack
@EnTeQuAk: Ich denke das Hauptproblem ist, dass Du hier gegen die Sprache kämpfst. Letztendlich kann man es nur herausfinden, indem man es tut, und da ist der vorgeschlagene `iter()`-Aufruf eine Methode. Auf `__iter__()` testen reicht nicht, weil auch Objekte, die per Zahlen indexierbar sind, iterierbar sein können, siehe zum Beispiel Zeichenketten.

Was ist denn überhaupt der Anwendungsfall? Auf Zeichenketten als Ausnahme würde ich mit `isinstance()` und `basestring` testen.

Verfasst: Sonntag 15. Juli 2007, 11:44
von EnTeQuAk
Was ist denn überhaupt der Anwendungsfall?
Eine art URL-System, für nen Blog-System.

Es geht darum, das es verschiedene Views gibt. Eine View ist sozusagen der handler eines requests und gibt die Ausgaben an den Clienten zurück.

Nun soll eine View aber unter mehreren URLs aufgerufen werden können.

Dazu gibt es das Attribut `rules`. Entweder Es gibt nur eine `URLRule` oder eine Liste, ein Tupel von `URLRule`s.

Das würde ich gerne teste, ob es eine oder mehrere sind.

MfG EnTeQuAk

Verfasst: Sonntag 15. Juli 2007, 11:53
von Joghurt
Warum nimmst du nicht grundsätzlich eine Liste an? Wenn du nur einen Eintrag "foo" hast, brauchst du nur ["foo"] oder ("foo",) zu schreiben...

Verfasst: Sonntag 15. Juli 2007, 12:48
von EnTeQuAk
Warum nimmst du nicht grundsätzlich eine Liste an? Wenn du nur einen Eintrag "foo" hast, brauchst du nur ["foo"] oder ("foo",) zu schreiben...
Währe die letzte Möglichkeit, die ich eingeschlagen hätte. Aber vermutlich wirds so wohl am besten/einfachsten sein.


Danke nochmal!


MfG EnTeQuAk

Verfasst: Sonntag 15. Juli 2007, 12:55
von nkoehring
...und wenn du sicher sein kannst, dass es entweder ein einzelnes Objekt oder eine Liste bzw ein Tuple ist, dann kannst du auch einfach auf eben die beiden letzteren testen:

Code: Alles auswählen

def is_multiple(obj):
    return type(obj)!=list and type(obj)!=tuple
Also das ist jetzt nur schnell zusammengehackt, sollte aber eigentlich funktionieren.

Verfasst: Sonntag 15. Juli 2007, 14:00
von veers
Hm, wie wäre es wenn du Strings Extra behandelst und nicht iterables. Irgend wie so:

Code: Alles auswählen

if is_iterable(x) and type(x) is not str:
    return x
return (x, )

Verfasst: Sonntag 15. Juli 2007, 14:28
von BlackJack
Nochmal: auf Zeichenketten bitte mit ``isinstance(obj, basestring)`` testen. So erwischt man auch Unicode-Zeichenketten und alles was von `str` und `unicode` abgeleitet ist.

Verfasst: Sonntag 15. Juli 2007, 15:23
von veers
BlackJack hat geschrieben:Nochmal: auf Zeichenketten bitte mit ``isinstance(obj, basestring)`` testen. So erwischt man auch Unicode-Zeichenketten und alles was von `str` und `unicode` abgeleitet ist.
Wieder etwas gelernt :)

Verfasst: Sonntag 15. Juli 2007, 17:36
von Y0Gi
EnTeQuAk: Routes kommt für dich nicht in Frage?

Verfasst: Sonntag 15. Juli 2007, 19:03
von EnTeQuAk
EnTeQuAk: Routes kommt für dich nicht in Frage?
Ich benutze das Routing-System von Werkzeug.

Und da gibt es halt für jede View eine oder mehrere `Rules`. Da wollte ich halt die Möglichkeit bieten, entweder eine einzelne Route hinzuschreiben oder eine Liste/Tupel.

Man könnte auf Instanz mit `Route` prüfen... ginge auch. Ich habe jetzt einfach vorgegeben, das eine View immer eine Liste in mit `Route`s definieren soll. Wie viele da drinne ist, ist ja letzendlich egal.


MfG EnTeQuAk

Verfasst: Sonntag 15. Juli 2007, 21:10
von birkenfeld
BlackJack hat geschrieben:Nochmal: auf Zeichenketten bitte mit ``isinstance(obj, basestring)`` testen. So erwischt man auch Unicode-Zeichenketten und alles was von `str` und `unicode` abgeleitet ist.
Und ansonsten vergleicht man Typen mit `is`, nicht mit `==` (@diverse Poster).

Verfasst: Sonntag 15. Juli 2007, 23:19
von Y0Gi
BlackJack hat geschrieben:Nochmal: auf Zeichenketten bitte mit ``isinstance(obj, basestring)`` testen. So erwischt man auch Unicode-Zeichenketten und alles was von `str` und `unicode` abgeleitet ist.
Und die Oldschooler (pre-2.3) benutzen ``isinstance(obj, (str, unicode))`` um dasselbe zu erreichen.