
Moin Moin, Ich weiss, wahrscheinlich ziemlich billige Frage aber ich komm einfach nicht drauf: Wie kann ich eine Variable testen ob es eine Liste ist oder ein String? Vielen Dank für die Hilfe an einen blinden Newbie mfg freakTAB _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

--On 15. Dezember 2005 14:41:26 +0100 Tino Schmedemann <freakTAB@nbnet.de> wrote:
Moin Moin, Ich weiss, wahrscheinlich ziemlich billige Frage aber ich komm einfach nicht drauf: Wie kann ich eine Variable testen ob es eine Liste ist oder ein String? Vielen Dank für die Hilfe an einen blinden Newbie
isinstance(obj, list) isinstance(obj, str) -aj _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Am Donnerstag, den 15.12.2005, 14:41 +0100 schrieb Tino Schmedemann:
Moin Moin, Ich weiss, wahrscheinlich ziemlich billige Frage aber ich komm einfach nicht drauf: Wie kann ich eine Variable testen ob es eine Liste ist oder ein String? Vielen Dank für die Hilfe an einen blinden Newbie
type("Hallo") type(["Hallo","Tino"]) Grusz aus der Enklave
mfg freakTAB
_______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de
_______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Tino Schmedemann:
Wie kann ich eine Variable testen ob es eine Liste ist oder ein String?
isinstance(var, list), isinstance(var, str), isinstance(var, tuple) Aber willst Du das wirklich? In Python versucht man meist gerade keinen bestimmten Typ vorzuschreiben, sondern probiert einfach die Operationen auf dem Objekt, die man machen will. Exceptions fangen kann man immer noch. Stichwort "duck typing". J. -- When standing at the top of beachy head I find the rocks below very attractive. [Agree] [Disagree] <http://www.slowlydownward.com/NODATA/data_enter2.html> _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

--On 15. Dezember 2005 15:01:47 +0100 Jochen Schulz <ml@well-adjusted.de> wrote:
Aber willst Du das wirklich? In Python versucht man meist gerade keinen bestimmten Typ vorzuschreiben, sondern probiert einfach die Operationen auf dem Objekt, die man machen will.
Wer hat Dir denn diesen Blödsinn beigebracht? Bis Du PHP/Perl Programmierer? :-) -aj _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Andreas Jung schrieb:
--On 15. Dezember 2005 15:01:47 +0100 Jochen Schulz <ml@well-adjusted.de> wrote:
Aber willst Du das wirklich? In Python versucht man meist gerade keinen bestimmten Typ vorzuschreiben, sondern probiert einfach die Operationen auf dem Objekt, die man machen will.
Wer hat Dir denn diesen Blödsinn beigebracht? Bis Du PHP/Perl Programmierer? :-)
Ähem. Ohne jetzt einen Religionskrieg auslösen zu wollen: Duck-Typing ist ein gängiges Konzept in Python, das in vielen Fällen Vorteile mit sich bringt. Natürlich könnte ich nachschauen, ob ein Objekt eine Liste, ein String, ein Tuple, oder ... ist. Wenn es mir aber z.B. nur darum geht, dass es aufzählbar ist, dann tue ich das nicht (ich könnte ohnehin nicht alle aufzählbaren Typen abtesten). Also nutze ich einfach ein for value in object: print value und lasse es mir egal sein, was für einen Iterator ich da jetzt gerade vor mir habe. Ähnliches gilt in vielen anderen Fällen. Gruß, Stefan _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

On Thursday 15 December 2005 15:12, Andreas Jung wrote:
--On 15. Dezember 2005 15:01:47 +0100 Jochen Schulz <ml@well-adjusted.de>
wrote:
Aber willst Du das wirklich? In Python versucht man meist gerade keinen bestimmten Typ vorzuschreiben, sondern probiert einfach die Operationen auf dem Objekt, die man machen will.
Wer hat Dir denn diesen Blödsinn beigebracht? Bis Du PHP/Perl Programmierer? :-)
So einen Bloedsinn verzapft uA Alex Martelli, Autor des Cookbooks und sicher einer der profiliertesten Python-Coder weltweit: http://groups.google.com/group/comp.lang.python/browse_frm/thread/82b36a09772bb37/e230ca916be58835?lnk=st&q=martelli+duck+typing+python&rnum=6&hl=en#e230ca916be58835 MfG Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Sorry für das Zerreissen des Threads. Ich hatte zwei Antworten, die in meiner Inbox landeten gelöscht, weil ich Kopien an die Liste erwartete. On Thursday 15 December 2005 15:12, Andreas Jung wrote:
--On 15. Dezember 2005 15:01:47 +0100 Jochen Schulz <ml@well-adjusted.de>
Aber willst Du das wirklich? In Python versucht man meist gerade keinen bestimmten Typ vorzuschreiben, sondern probiert einfach die Operationen auf dem Objekt, die man machen will.
Wer hat Dir denn diesen Blödsinn beigebracht?
Zum Beispiel das Python-Tutorial: <http://docs.python.org/tut/node18.html#l2h-46> :-) Was mir auch grad noch einfällt: da es in Python kein Problem ist, zur Laufzeit einer Klasse Methoden zu klauen (und damit auch allen bereits instanzierten Objekten!), kann man mit isinstance() sowieso mächtig auf die Nase fallen: <<< class C(object): ... def f(self): pass ... <<< c = C() <<< del C.f <<< isinstance(c, C) True <<< c.f() Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'C' object has no attribute 'f' Gut, das geht mit den built-in Types nicht, aber deswegen ist isinstance() trotzdem kein besserer Stil.
Bis Du PHP/Perl Programmierer? :-)
Keins von beidem. Ok, ein paar Zeilen Perl habe ich mal geschrieben, aber das ist fast drei Jahre her. J. -- My memories gild my life with rare transcendance. [Agree] [Disagree] <http://www.slowlydownward.com/NODATA/data_enter2.html> _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Was mir auch grad noch einfällt: da es in Python kein Problem ist, zur Laufzeit einer Klasse Methoden zu klauen (und damit auch allen bereits instanzierten Objekten!), kann man mit isinstance() sowieso mächtig auf die Nase fallen:
<<< class C(object): ... def f(self): pass ... <<< c = C() <<< del C.f <<< isinstance(c, C) True <<< c.f() Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'C' object has no attribute 'f'
Naja, das ist ja auch etwas sehr boesartig.
Gut, das geht mit den built-in Types nicht, aber deswegen ist isinstance() trotzdem kein besserer Stil.
Auch wenn ich oft type() verwende, hat Andreas da durchaus recht - isinstance wird in der python-Doku zu type() als bessere Alternative empfohlen. Und klappt zb auch hier:
class Foo(list): ... pass ... l = Foo() type(l) == list False isinstance(l, list) True
MfG Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Diez B. Roggisch:
Jochen Schulz:
<<< del C.f
Naja, das ist ja auch etwas sehr boesartig.
Keine Frage. Worauf ich hinauswollte: wenn ich mich konsequent um Interfaces kümmere, statt um Typen, gewinne ich viel (siehe file-like objects) und erschlage damit selbst solches Fehlverhalten. J. -- Quite often I wonder why I am not more famous and/or more wealthy. [Agree] [Disagree] <http://www.slowlydownward.com/NODATA/data_enter2.html> _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

On Thursday 15 December 2005 16:54, Jochen Schulz wrote:
Diez B. Roggisch:
Jochen Schulz:
<<< del C.f
Naja, das ist ja auch etwas sehr boesartig.
Keine Frage.
Worauf ich hinauswollte: wenn ich mich konsequent um Interfaces kümmere, statt um Typen, gewinne ich viel (siehe file-like objects) und erschlage damit selbst solches Fehlverhalten.
Nein, nicht wirklich, das ist IMHO sehr akademisch betrachtet - und praktisch kommen wir denke ich zum selben Ergebnis: - in Python setzt man ein bestimmtes Protokoll/Verhalten vorraus. Entweder implizit, durch Benutzung, oder explizit. Was man nur selten braucht, zb um strings von iterables zu unterscheiden um nicht aus versehen ueber die Buchstaben zu laufen. - wenn explizit, dann ist type() oder isinstance() das Mittel der Wahl, letzteres ist sicher leistungsfaehiger - auch wenn man das weniger selbstgerecht als Andreas feststellen kann. Was IMHO fuer die Tiefe der aktuellen Diskussion wesentlich einflussreicher ist als die Unterschiede im Programmierstil der Beteiligten .... :) Dein Ansatz wuere ja genau bedeuten das man einen quasi-statischen Ansatz faehrt und _alle_ potentiellen Methoden abfragt - bei files zB read, write aber auch readlines usw. Das macht ja niemand wirklich. Stattdessen wuerde man in dem Fall eben class MyFileUrsurper(file): def read(self): .... .... usw. machen und dann mittels isinstance(foo, file) darauf pruefen und sich darauf verlassen das dann schon alles da sein wird. MfG Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

--On 15. Dezember 2005 16:12:17 +0100 Jochen Schulz <ml@well-adjusted.de> wrote:
<<< class C(object): ... def f(self): pass ... <<< c = C() <<< del C.f <<< isinstance(c, C) True <<< c.f() Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'C' object has no attribute 'f'
Gut, das geht mit den built-in Types nicht, aber deswegen ist isinstance() trotzdem kein besserer Stil.
Wieso würde Dir type() hier weiterhelfen? Mit konstruierten Beispielen kann man für alles Gegenargumente konstruieren. Du hast noch kein einziges Argument gebracht, warum type() isinstance() vorzuziehen wäre. -aj _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Bitte keine Kopien an mich. Andreas Jung:
Du hast noch kein einziges Argument gebracht, warum type() isinstance() vorzuziehen wäre.
Du, das könnte daran liegen, dass ich das zu keinem Zeitpunkt behauptet habe. :-) Wenn Du meine erste Mail im Thread nochmal liest, wirst Du feststellen, dass ich auch isinstance() vorgeschlagen habe. Ich habe lediglich das allgemeine Vorgehen in Frage gestellt. Der Typ eines Objekts sagt in Python nicht zwangsläufig etwas über die vorhandenen Attribute aus. Dafür habe ich eins von vielen möglichen Beispielen konstruiert. Deswegen prüft man idealerweise mit hasattr() (und meinetwegen noch callable(), wenn man eine Methode haben will) oder lässt die Prüferei ganz sein und fängt die entsprechenden Exceptions. Duck-Typing ist IMHO gerade die Stärke, die man sich durch die fehlende "Typsicherheit" erkauft. Es wäre Verschwendung, diesen Vorteil mutwillig wegzuwerfen. J. -- Looking into my eyes is the only way you'll know I'm telling the truth. [Agree] [Disagree] <http://www.slowlydownward.com/NODATA/data_enter2.html> _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Diez B. Roggisch schrieb:
On Thursday 15 December 2005 15:12, Andreas Jung wrote:
--On 15. Dezember 2005 15:01:47 +0100 Jochen Schulz <ml@well-adjusted.de>
wrote:
Aber willst Du das wirklich? In Python versucht man meist gerade keinen bestimmten Typ vorzuschreiben, sondern probiert einfach die Operationen auf dem Objekt, die man machen will.
Wer hat Dir denn diesen Blödsinn beigebracht? Bis Du PHP/Perl Programmierer? :-)
So einen Bloedsinn verzapft uA Alex Martelli, Autor des Cookbooks und sicher einer der profiliertesten Python-Coder weltweit:
Duck-Typing bedeutet keinesfalls, dass man einfach Operationen auf einem Objekt ausfuehrt, ohne zu pruefen, ob das Objekt diese Operationen auch zur Verfuegung stellt. Duck-Typing bedeutet lediglich, dass man nicht den Typ eines Objektes erfragt, um vom Typ des Objektes auf die implementierte Schnittstelle zu schliessen, sondern man prueft stattdessen, ob das Objekt die benoetigte Schnittstelle implementiert. Die Betonung liegt auf pruefen. Eine Operation einfach zu probieren und eventuelle Fehler abzufangen wuerde ich eher Try-And-Error nennen und hat mit Duck-Typing nicht viel zu tun. Zitat: "In other words, don't check whether it IS-a duck: check whether it QUACKS-like-a duck, WALKS-like-a duck, etc, etc, depending on exactly what subset of duck-like behaviour you need to play your language-games with." Allen, die vor der Ausfuehrung von Operationen nicht pruefen wollen (egal ob Typ oder Schnittstelle), sondern lieber die Operation einfach ausfuehren und den Fehlerfall mit try/except fangen, moechte ich das angehaengte Script nahelegen. Mal abgesehen davon, dass ich Try-And-Error fuer ganz schlechten Stil halte und es der Lesbarkeit nicht gerade zutraeglich ist, hat das Vefahren auch erhebliche Auswirkungen auf die Performance. Ich halte mich an folgende Regeln: 1.) Ich verwende type() wenn moeglich oder zwingend notwendig. 2.) Ich verwende isinstance() wenn type() nicht geht (wg. Ableitungen). 3.) Duck-Typing kommt nur dann zur Anwendung, wenn ich vom Typ eines Objektes nicht auf seine implemetierte Schnittstelle schliessen kann, z. B. wenn die Schnittstelle eines Objektes zur Laufzeit erzeugt oder veraendert wird. 4.) Try-And-Error vermeide ich moeglichst immer. --- Ulli import time # Diese Konvertierungs-Funktion verwendet type(), # um den Typ des Objektes zu erfragen. Das ist nur # dann brauchbar, wenn ich nicht mit Ableitungen # des Typs rechnen muss. def f1(obj): if type(obj) == str: return obj.lower() elif type(obj) == int: return hex(obj) elif type(obj) == float: return abs(obj) return obj # Diese Konvertierungs-Funktion verwendet isinstance(), # um den Typ des Objektes zu erfragen. Das funktioniert # auch bei Ableitungen des Typs. def f2(obj): if isinstance(obj, str): return obj.lower() elif isinstance(obj, int): return hex(obj) elif isinstance(obj, float): return abs(obj) return obj # Dies ist Duck-Typing. Anstatt den Typ des Objektes zu # erfragen und vom Typ des Objektes auf die implemetierte # Schnittstelle zu schliessen, wird die Schnittstelle # des Objektes erfragt. Man kann schon erkennen, dass das # aufgrund der unten definierten Regeln problematisch werden # kann. def f3(obj): if hasattr(obj, 'lower'): return obj.lower() elif hasattr(obj, '__hex__'): return hex(obj) elif hasattr(obj, '__abs__'): return abs(obj) return obj # Dies ist Try-And-Error. Wir versuchen einfach die # Operation auszufuehren und fangen auftretende Fehler ab. def f4(obj): try: return obj.lower() except (AttributeError, TypeError): pass try: return hex(obj) except (AttributeError, TypeError): pass try: return abs(obj) except (AttributeError, TypeError): pass return obj # # Main # if __name__ == '__main__': records = ((("A", "B", "C", 1, 2, 3, 0.1, 0.2, -0.3, None, "D", "E", "F", 4, 5, 6, 0.4, 0.5, -0.6, None),)*100000) print "Verarbeite %d Datensaetze mit %d Spalten..." % (len(records), len(records[0])) print print "Regeln:" print "1.) Alle Strings in Kleinbuchstaben konvertieren." print "2.) Alle Integers in Hex-Strings konvertieren." print "3.) Von allen Floats wird der Absolutwert gebildet." print "4.) Alle anderen Typen bleiben unmodifiziert." print start_time = time.time() for record in records: for column in record: f1(column) print "%.3f Sek. mit type()" % (time.time() - start_time) start_time = time.time() for record in records: for column in record: f2(column) print "%.3f Sek. mit isinstance()" % (time.time() - start_time) start_time = time.time() for record in records: for column in record: f3(column) print "%.3f Sek. mit hasattr()" % (time.time() - start_time) start_time = time.time() for record in records: for column in record: f4(column) print "%.3f Sek. mit try/except" % (time.time() - start_time) _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

On Friday 16 December 2005 11:51, Ulrich Berning wrote:
Duck-Typing bedeutet keinesfalls, dass man einfach Operationen auf einem Objekt ausfuehrt, ohne zu pruefen, ob das Objekt diese Operationen auch zur Verfuegung stellt. Duck-Typing bedeutet lediglich, dass man nicht den Typ eines Objektes erfragt, um vom Typ des Objektes auf die implementierte Schnittstelle zu schliessen, sondern man prueft stattdessen, ob das Objekt die benoetigte Schnittstelle implementiert. Die Betonung liegt auf pruefen.
Stimmt das? Wenn ich zB (c)StringIO hernehme - dann kann ich das ueberall da reingeben wo der Autor eines anderen Paketes files angedacht hat. Und genau darum geht es doch: er (der andere Autor) wird doch nicht hingehen und alle eventualitaeten pruefen, sondern eben einfach das machen, was er mit dem vermeintlichen Stream anfangen wollte. Die Pruefung erfolgt dabei eben implizit, durch Anwendung seiner benoetigten Operationne - und genau das verstehe ich unter Duck-Typing. Um bei Alex' Beispiel zu bleiben:
"In other words, don't check whether it IS-a duck: check whether it QUACKS-like-a duck, WALKS-like-a duck, etc, etc, depending on exactly what subset of duck-like behaviour you need to play your language-games with."
some_bird.quack() some_bird.walk() statt try: some_bird.quack some_bird.walk except AttributeError: print "I want a duck!" raise Letzteres ist das, was ich deiner Aussage entnehme und dem angehangenen Skript.
Ich halte mich an folgende Reeln: 1.) Ich verwende type() wenn moeglich oder zwingend notwendig. 2.) Ich verwende isinstance() wenn type() nicht geht (wg. Ableitungen). 3.) Duck-Typing kommt nur dann zur Anwendung, wenn ich vom Typ eines Objektes nicht auf seine implemetierte Schnittstelle schliessen kann, z. B. wenn die Schnittstelle eines Objektes zur Laufzeit erzeugt oder veraendert wird. 4.) Try-And-Error vermeide ich moeglichst immer.
Mit Ausnahme von 3 - da haben wir wohl etwas divergierende Vorstellungen - sehe ich das genauso. MfG Diez _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Diez B. Roggisch schrieb:
Die Pruefung erfolgt dabei eben implizit, durch Anwendung seiner benoetigten Operationne - und genau das verstehe ich unter Duck-Typing.
Wie sagt man doch so schön? We're all adults.
Ich halte mich an folgende Regeln: 1.) Ich verwende type() wenn moeglich oder zwingend notwendig. 2.) Ich verwende isinstance() wenn type() nicht geht (wg. Ableitungen).
Was sicherlich so oft der Fall ist, dass type() ernsthaft Seltenheitscharakter verdient. Warum sollte ich mir meinen Code kaputt machen, nur, weil ich später irgendwann auf die Idee komme, dass ich eine Subklasse brauche, die irgendwas macht, was das Original nicht konnte? Ist für mich eigentlich Teil des Sinns und Zwecks von OO. Und das trifft insbesondere auf die Standardklassen zu: Mappings, Sequenzen, Iterables, Files, Zeichenfolgen, ...
3.) Duck-Typing kommt nur dann zur Anwendung, wenn ich vom Typ eines Objektes nicht auf seine implemetierte Schnittstelle schliessen kann, z. B. wenn die Schnittstelle eines Objektes zur Laufzeit erzeugt oder veraendert wird. 4.) Try-And-Error vermeide ich moeglichst immer.
Mit Ausnahme von 3 - da haben wir wohl etwas divergierende Vorstellungen -
Dem schließe ich mich an. Stefan _______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de

Ich hab ganz gute Erfahrungen mit "isinstance(xxx,basestring)" gemacht, das sowohl 'str' als auch 'unicode' objekte von 'basestring' erben. Wenn man nur auf 'str' testet, kann man Probleme bekommen, wenn spaeter mal auf unicode umgestellt werden muss. Stephan On Thursday 15 December 2005 14:41, Tino Schmedemann wrote:
Moin Moin, Ich weiss, wahrscheinlich ziemlich billige Frage aber ich komm einfach nicht drauf: Wie kann ich eine Variable testen ob es eine Liste ist oder ein String? Vielen Dank für die Hilfe an einen blinden Newbie
mfg freakTAB
_______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de
participants (8)
-
Andreas Jung
-
Diez B. Roggisch
-
Jochen Schulz
-
Mathias Uebel
-
Stefan Behnel
-
Stephan Diehl
-
Tino Schmedemann
-
Ulrich Berning