Seite 1 von 1

is integer ?

Verfasst: Sonntag 5. November 2006, 01:21
von thonix
Moin zusammen,

ich hoffe eine einfache Frage ;-)
gibt es eine Funtion die Überprüft ob ein Wert in einer Variablen ein int ist ?

Danke

Thonix

Verfasst: Sonntag 5. November 2006, 01:34
von mitsuhiko

Code: Alles auswählen

>>> type(42) is int
True
>>> isinstance(42, int)
True
>>> (42).__class__ is int
True
Die Erste nimmst du, wenn du Kinderklassen ausschließen willst. Die zweite, wenn du die auch zulassen willst. Dritte nimm gar nicht :D

Verfasst: Sonntag 5. November 2006, 10:56
von Joghurt
Überlege dir aber, warum du das wissen willst. Typabfragen sind häufig ein Zeichen dafür, dass du Programmierparadigmen aus einer anderen Sprache versuchst auf Python anzuwenden; meistens versuchst du den "Look before you leap"-Ansatz, den man in Java und C++ kennt, nachzubasteln.

In Python interessiert es einen nicht, mit was für einem Typ man es zu tun hat, solange er die benutzen Funktionen unterstützt.

Wenn dein Code z.B. zwei Integers addieren will, und du explizit auf Integer prüfst, kann ich nicht meinen Typ "Element von F(5003)" übergeben, auch wenn meiner sich addieren lässt.

Verfasst: Sonntag 5. November 2006, 13:05
von thonix
Danke für die Antworten.

ich muss einen wert an eine Funktion weitergeben die unzureichende Typprüfungen macht und auch nur eine dürftige exception schmeißt.
Wenn dein Code z.B. zwei Integers addieren will, und du explizit auf Integer prüfst, kann ich nicht meinen Typ "Element von F(5003)" übergeben, auch wenn meiner sich addieren lässt.
Versteh ich leider nicht - kansst du das noch mal erläutern - bin ja wissbegierig :D

Thonix

Verfasst: Sonntag 5. November 2006, 13:58
von Leonidas
thonix hat geschrieben:ich muss einen wert an eine Funktion weitergeben die unzureichende Typprüfungen macht und auch nur eine dürftige exception schmeißt.
Optimalerweise nutzt man in Python wie gesagt eben keine Typprüfungen.
thonix hat geschrieben:
Wenn dein Code z.B. zwei Integers addieren will, und du explizit auf Integer prüfst, kann ich nicht meinen Typ "Element von F(5003)" übergeben, auch wenn meiner sich addieren lässt.
Versteh ich leider nicht - kansst du das noch mal erläutern - bin ja wissbegierig :D
Okay, gehen wir davon aus dass jemand sich diese Klasse geschrieben hat, d.h einen Integer-Datentyp der sich wie ein Integer verhält aber noch andere Sachen kann:

Code: Alles auswählen

In [2]: class IntLike(int):
   ...:     def wichtige_extra_funktion(self):
   ...:         print 'Jetzt mache ich was ganz wichtiges'
Na dann schauen wir mal ob es sich wie ein Integer verhält:

Code: Alles auswählen

In [3]: il = IntLike(250188)
In [4]: il
Out[4]: 250188
In [5]: il + 1
Out[5]: 250189
Okay, wir sehen nun, das sich dieser Integer-Datentyp wie ein ganz normaler Integer verhält, aber auch zusätzlich irgendwas tolles kann:

Code: Alles auswählen

In [6]: il.wichtige_extra_funktion()
Jetzt mache ich was ganz wichtiges
Jetzt definieren wir mal eine simple Funktion mit Typabfrage:

Code: Alles auswählen

In [7]: def addiere_eins(zahl):
   ...:     if type(zahl) is int:
   ...:         return zahl + 1
   ...:     else:
   ...:         raise TypeError('Kein int')
Rufen wir sie mit einem normalen Integer auf, funktioniert sie:

Code: Alles auswählen

In [8]: addiere_eins(250188)
Out[8]: 250189
Nun versuchen wir es mal mit unserem abgeleitetem Integer, der sich ja wie gesagt wie ein Integer verhält:

Code: Alles auswählen

In [9]: addiere_eins(il)
---------------------------------------------------------------------------
<type 'exceptions.TypeError'>             Traceback (most recent call last)

/home/marek/<ipython console> in <module>()

/home/marek/<ipython console> in addiere_eins(zahl)

<type 'exceptions.TypeError'>: Kein int
Oh, geht nicht, weil die Typabfrage sagt, dass unser IntLike kein Int ist. Aber er verhält sich wie ein Integer und wird trotzdem nicht akzeptiert!

Daher schreibt man addiere_eins() in Python so:

Code: Alles auswählen

In [10]: def addiere_eins(zahl):
   ....:     return zahl + 1
Das ist erstens kürzer und zweitens universeller:

Code: Alles auswählen

In [11]: addiere_eins(250188)
Out[11]: 250189
In [12]: addiere_eins(il)
Out[12]: 250189
Das ganze nennt sich Duck Typing, ein Begriff der sich in der Python-Welt bisher leider nicht richtig durchgesetzt. Aber sowohl Ruby als auch Python unterstützen Duck Typing gleichermaßen. Kurz zusammengefasst: "It looks like a duck, it quacks like a duck, then it must be a duck.", auf unser Integer-Beispiel bezogen: "It looks like an integer, it acts like an integer, so it must me an integer then.".

Verfasst: Sonntag 5. November 2006, 14:37
von BlackJack
Man muss ja noch nicht einmal einen selbstgeschriebenen Typ verwenden. Ich würde zum Beispiel von fast jeder Funktion, die ganze Zahlen haben möchte, erwarten das sie auch mit `long` funktioniert:

Code: Alles auswählen

In [33]: type(42L) is int
Out[33]: False
Ups.

Verfasst: Montag 6. November 2006, 11:51
von birkenfeld
Deswegen nimmt man ja auch isinstance(x, (int, long)), wenn man wirklich nur Pythons Integer-Typen zulassen will.

Verfasst: Dienstag 7. November 2006, 20:26
von Joghurt
birkenfeld hat geschrieben:Deswegen nimmt man ja auch isinstance(x, (int, long)), wenn man wirklich nur Pythons Integer-Typen zulassen will.
Aber wer will das schon? Ist ziemlich unpythonic!

Re: is integer ?

Verfasst: Dienstag 7. November 2006, 22:15
von gerold
thonix hat geschrieben:gibt es eine Funtion die Überprüft ob ein Wert in einer Variablen ein int ist?
Hi Thonix!

Eine, meiner bescheidenen Meinung nach, wichtige Alternative wurde noch nicht angesprochen.

Es schränkt ziemlich ein, wenn du prüfst, ob ein Wert ein INT ist. Wenn du den Wert aber nach INT umzuwandeln versuchst, dann kannst du sogar LONG oder STRING übergeben und trotzdem funktioniert das Ganze.

Code: Alles auswählen

def verdopple_ganzzahl(zahl):
    zahl = long(zahl)
    return zahl * 2
So wird ein Fehler ausgelöst, wenn sich die ``zahl`` nicht umwandeln lässt, es gibt aber keinen Fehler, wenn keine LONG-Zahl übergeben wurde. Viel mehr Freiheit -- denke ich.

Zumindest kann dann nicht so etwas unerwartetes von der Funktion zurück gegeben werden, wie in diesem Fall:

Code: Alles auswählen

def verdopple_ganzzahl(zahl):
    return zahl * 2

print verdopple_ganzzahl("123.33") # --> '123.33123.33'
mfg
Gerold
:-)