nach Iterierbarkeit fragen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Goswin
User
Beiträge: 361
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen

nach Iterierbarkeit fragen

Beitragvon Goswin » Mittwoch 8. April 2009, 17:18

Wie frage ich bloß, ob ein Objekt X iterierbar ist oder nicht? Ein eingebautes "isiterable(X)" gibt es anscheinend nicht, oder habe ich etwas übersehen?
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Beitragvon str1442 » Mittwoch 8. April 2009, 17:34

Wozu? Der bevorzugte Weg ist, einfach anzunehmen das es iterierbar ist. Sollte das nicht der Fall sein bekommt man eine nette Exception. Ansonsten kannst du auch hasattr(obj, "__iter__") benutzen, aber manche Objekte sind auch iterable, wenn sie __iter__ nicht besitzen - diese Objekte haben eine __len__ + __getitem__ Methode und werden von iter() dann mit den entsprechenden range() Werten gefüttert. IIRC sollte dieses Verhalten aber in Python 3 verschwunden sein (richtig?).
Benutzeravatar
Goswin
User
Beiträge: 361
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen

Beitragvon Goswin » Mittwoch 8. April 2009, 17:49

Oder vielleicht so etwas?

Code: Alles auswählen

def isiterable(X):
  try:
    for x in X: break
    return True
  except TypeError:
    return False


Ich möchte gleich am Anfang eines Funktionsaufrufes testen können, ob die Argumente der Funktion sinnvoll sind oder nicht, und möchte nicht erst lange warten und Daten durcheinanderwürfeln, bevor die Exception kommt.
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

Beitragvon name » Mittwoch 8. April 2009, 17:52

Goswin hat geschrieben:Oder vielleicht so etwas?

Code: Alles auswählen

def isiterable(X):
  try:
    for x in X: break
    return True
  except TypeError:
    return False


Ich möchte gleich am Anfang eines Funktionsaufrufes testen können, ob die Argumente der Funktion sinnvoll sind oder nicht, und möchte nicht erst lange warten und Daten durcheinanderwürfeln, bevor die Exception kommt.
Bloederweise verbrauchst du so ein element des Iterators. In Python prueft man die Argumente normalweise nicht, sondern lasst die exception einfach dann raisen wann sie kommt.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
DasIch
User
Beiträge: 2405
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Beitragvon DasIch » Mittwoch 8. April 2009, 17:53

Statt tatsächlich darüber zu iterieren sollte man versuchen mit iter() einen Iterator zu erzeugen.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Mittwoch 8. April 2009, 18:02

str1442 hat geschrieben:diese Objekte haben eine __len__ + __getitem__ Methode und werden von iter() dann mit den entsprechenden range() Werten gefüttert. IIRC sollte dieses Verhalten aber in Python 3 verschwunden sein (richtig?).

`__len__` ist nicht nötig. Python versucht einfach `__getitem__` mit numerischen Indizes beginnend mit 0 und dann aufsteigend so lange aufzurufen, bis es zu einem IndexError kommt. Dieses Verhalten ist auch noch in Python 3.x dokumentiert.

Stefan
Benutzeravatar
Goswin
User
Beiträge: 361
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen

Beitragvon Goswin » Mittwoch 8. April 2009, 18:10

Schön, dann hätte ich ja schon 2 Alternativen, wofür ich mich vielmals bedanke:

Code: Alles auswählen

def isiterable(X):
  return hasattr(X,'__iter__')

Code: Alles auswählen

def isiterable(X):
  try: iter(X); return True
  except TypeError: return False


Die erste Alternative ist laut str1442 weniger gut für Python_2.x, und laut sma wird das in Python_3.x anscheinend nicht anders sein. Sollen wir die zweite Alternative zum Gewinner erklären?
DasIch
User
Beiträge: 2405
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Beitragvon DasIch » Mittwoch 8. April 2009, 18:40

Ja, wenn man den SyntaxError behebt und nicht so mit Zeilen geizt.
Benutzeravatar
Goswin
User
Beiträge: 361
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen

Beitragvon Goswin » Mittwoch 8. April 2009, 19:05

Code: Alles auswählen

def isiterable(X):
  try: iter(X); return True
  except TypeError: return False


@Dasich:
Ich habe den Code getestet und er scheint bei Python_2.5 einwandfrei zu funktionieren. Hat er einen Syntaxfehler von Python_3.x?
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

Beitragvon name » Mittwoch 8. April 2009, 19:06

Schrecklich aussehen tut er trotzdem.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Beitragvon derdon » Mittwoch 8. April 2009, 19:07

Als Parameter würde ich obj statt X nehmen.
DasIch
User
Beiträge: 2405
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Beitragvon DasIch » Mittwoch 8. April 2009, 19:09

Hab dass mit dem Semikolon falsch interpretiert. Trotzdem ist 3 Zeilen in eine zu pressen kein Zeichen von sonderlich schönem Code. Wenn man sowas wie try except, if elif else o.ä. hat macht dies den Code deutlich schwerer zu lesen.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Mittwoch 8. April 2009, 19:12

Goswin hat geschrieben:Hat er einen Syntaxfehler von Python_3.x?

Nein.
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

Beitragvon mzh » Mittwoch 8. April 2009, 19:20

Python > 3.0 hat definitiv kein hasattr() mehr, dort läufts über getattr(obj, '__name__').
[url=http://www.proandkon.com]proandkon.com[/url]
DasIch
User
Beiträge: 2405
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Beitragvon DasIch » Mittwoch 8. April 2009, 19:22

mzh hat geschrieben:Python > 3.0 hat definitiv kein hasattr() mehr, dort läufts über getattr(obj, '__name__').

Code: Alles auswählen

Python 3.0.1 (r301:69556, Feb 22 2009, 14:12:04)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> hasattr
<built-in function hasattr>

Da muss ich wohl ein anderes Python haben.

Wer ist online?

Mitglieder in diesem Forum: r.barrios