nach Iterierbarkeit fragen
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?).
- Goswin
- User
- Beiträge: 363
- Registriert: Freitag 8. Dezember 2006, 11:47
- Wohnort: Ulm-Böfingen
- Kontaktdaten:
Oder vielleicht so etwas?
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.
Code: Alles auswählen
def isiterable(X):
try:
for x in X: break
return True
except TypeError:
return False
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.Goswin hat geschrieben:Oder vielleicht so etwas?
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.Code: Alles auswählen
def isiterable(X): try: for x in X: break return True except TypeError: return False
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.
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.
`__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.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?).
Stefan
- Goswin
- User
- Beiträge: 363
- Registriert: Freitag 8. Dezember 2006, 11:47
- Wohnort: Ulm-Böfingen
- Kontaktdaten:
Schön, dann hätte ich ja schon 2 Alternativen, wofür ich mich vielmals bedanke:
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?
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
- Goswin
- User
- Beiträge: 363
- Registriert: Freitag 8. Dezember 2006, 11:47
- Wohnort: Ulm-Böfingen
- Kontaktdaten:
Code: Alles auswählen
def isiterable(X):
try: iter(X); return True
except TypeError: return False
Ich habe den Code getestet und er scheint bei Python_2.5 einwandfrei zu funktionieren. Hat er einen Syntaxfehler von Python_3.x?
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.
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.
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.
Python > 3.0 hat definitiv kein hasattr() mehr, dort läufts über getattr(obj, '__name__').
[url=http://www.proandkon.com]proandkon.com[/url]
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>
Hm, keine Ahnung, wie ich darauf gekommen bin..
Ah, ich meinte callable.
Ah, ich meinte callable.
[url=http://www.proandkon.com]proandkon.com[/url]
@Goswin: Die zweite Variante ist genauso unzuverlässig wie die erste, denn ein Objekt das eine `__getitem__()`-Methode besitzt, aber nicht "iterable" ist, hat kein Problem mit dem `iter()`-Aufruf. Auch da "kracht" es erst, wenn man versucht von dem Iterator das erste Element zu holen.
Was letztendlich bedeutet, dass man nicht wirklich auf "iterable" prüfen kann, ohne das Objekt einfach so zu verwenden.
Was letztendlich bedeutet, dass man nicht wirklich auf "iterable" prüfen kann, ohne das Objekt einfach so zu verwenden.
Ab Python 2.6 geht das auch so:
Gruß,
Manuel
Code: Alles auswählen
from collections import Iterable
class Foo(object):
def __iter__(self):
pass
isinstance(list(), Iterable)
# True
isinstance(dict(), Iterable)
# True
isinstance(Foo(), Iterable)
# True
Manuel
@helduel: Aber auch bei 2.6 erkennt man so nicht alle "iterables":
Man muss es halt einfach probieren.
Code: Alles auswählen
>>> class A(object):
... def __getitem__(self, i):
... if i > 5:
... raise StopIteration()
... else:
... return i
...
>>> a = A()
>>> isinstance(a, Iterable)
False
>>> [x for x in a]
[0, 1, 2, 3, 4, 5]
- Goswin
- User
- Beiträge: 363
- Registriert: Freitag 8. Dezember 2006, 11:47
- Wohnort: Ulm-Böfingen
- Kontaktdaten:
name hat geschrieben:Schrecklich aussehen tut er [dein Code] trotzdem.
Am Anfang war Python noch script und stur,DasIch hat geschrieben:3 Zeilen in eine zu pressen [ist] 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.
da schuf BDFL das Semikolon und sprach:
"Zieh hinaus in alle Module und vermehre dich,
und sammelt um euch die Kleinen unter den Befehlen,
auf dass sie eng zusammenstehen
und ich sie gut übersehen kann"
Und da zogen Semikola ein in Klassen und Methoden,
und sammelten um sich die breaks und die returns,
und alle verwaisten x+=1 und list.sort(),
ein jegliches in seine vorangehende Codezeile.
Und BDFL sah, dass das Semikolon gut war,
und es wurde aus Alfa und Beta die Version t+1.