Seite 1 von 2
Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 19:51
von Strawk
Hallo!
Eine Funktion nested_sum soll die Elemente vom Typ integer, die in einer verschachtelten Liste sind (nested list) zusammen-/aufaddieren.
Ich möchte eine Exeption vom Typ TypeError werfen (und fangen?), wenn das zu untersuchende Einzelelement kein Integer ist und wenn die Einzelelemente nicht in einer verschachtelten Liste (nested list) sind. Bitte ein komplettes Beispiel, aus dem hervorgeht, WIE DER EXEPTION ÜBERHAUPT DER ERWARTETE TYP MITGETEILT WIRD.
Ich habe das gegoogelt, finde aber nur try- und catch-Blöcke, ohne dass ich wüsste, wie man der Exeption denn nun sagt: Hier muss eine Liste sein, sonst wirf, hier muss ein integer sein, sonst wirf.
Strawk

Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 20:19
von BlackJack
@Strawk: Das sagt man der Exception gar nicht. Eine Ausnahme prüft nichts, das musst Du selbst tun. Oder Du machst etwas ohne zu prüfen und das löst eine Ausnahme aus die Du behandeln kannst. Komplettes Beispiel um eine `TypeError`-Ausnahme auszulösen:
Komplettes Beispiel um eine `TypeError`-Ausnahme zu behandeln:
Code: Alles auswählen
try:
# irgendwas das einen TypeError auslösen kann
except TypeError as error:
# Hier *sinnvoll* (das ist *ganz* wichtig!) auf die Ausnahme reagieren
Der letzte Kommentar ist wirklich wichtig! Wenn man da nichts sinnvolles macht, dann sollte man es ganz bleiben lassen, denn das ist dann in dem Fall die sinnvollere Alternative.
Statt mit einer Suchmaschine solche Grundlagen zu suchen, macht es vielleicht mehr Sinn ein zusammenhängendes Tutorial für die Grundlagen zu verwenden. In der Python-Dokumentation befindet sich eins. Das hat auch ein Kapitel zu Ausnahmen und Ausnahmebehandlung.
Falls das eine Hausaufgabe ist, wird eventuell tatsächlich verlangt, das Du auf ganze Zahlen und Listen testest. Das verhindert allerdings, dass man auch andere addierbare Typen und Sequenzen verwendet. Eine generischere Lösung würde einfach versuchen die Objekte als iterier- und addierbar zu behandeln und entsprechend auf Ausnahmen reagieren. Also zum Beispiel die Iteration versuchen, und wenn das nicht geht, das Objekt als addierbar behandeln. Solltest Du auf Typen testen müssen, brauchst Du noch `isinstance()`. Oder `functools.singledispatch()` oder den Backport davon für Python 2.

Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 20:19
von __deets__
Der Exception wird nichts mitgeteilt. Die wird geworfen. WARUM sie geworfen wird liegt in deiner Hand. ZB weil du mit "isinstace(item, list)" geprueft hast, ob etwas eine Liste ist. Oder mit "isinstance(item, (int, long))" eine Ganzzahl.
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 20:50
von Strawk
Ich kann dem die zu verwendende Syntax nicht entnehmen. Ist da irgendwo ein "if" drin, muss das irgendwo ein "if" rein? Bitte ausführlicher, genauer. Danke! Wenn ich der Variable "l" einen Einzelwert zuweise, dann muss die Exeption ausgelöst werden, denn laut Aufgabe, MUSS es eine Liste sein. Dennoch löst l = 'willi' keine/n TypError aus, denn das ist eine legale Zuweisung. WO WIRD DER EXEPTION BEIGEBRACHT/MITGETEILT, was zulässig ist und was nicht?
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 20:59
von __deets__
Ja, es muss ein if darein. Denn wie du schon festgestellt hast ist das binden eines Namens keine Operation, bei der eine typprüfung stattfindet. Das musst du selbst machen.
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 21:02
von Strawk
Bitte den betreffenden Codeschnipsel hier komplett wiedergeben, inklusive
try
except
raise
catch
Wo kommt was hin und wo steht der If-Zweig? (Hier Beispiel nur Liste oder keine Liste)
Danke! :K
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 21:12
von BlackJack
@Strawk: Ich denke das ist *Deine* Aufgabe. Auch ``if`` ist Thema im Tutorial in der Python-Dokumentation.
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 21:27
von Strawk
Ich versuche mich seit 2009 in VBA und seit 2011 in PHP (zugegeben mit mäßigem Erfolg) und weiß, wie "if" funktioniert. Was ich nicht weiß und gern von euch wüsste: Wie und wo (rein von der Syntax/Befehlsabfolge her) wird definiert, DASS die Exception DANN geworfen werden soll.
Denn: Wenn y = 0 ist, wird x/y scheitern. l = 'willi' scheitert aber nicht; ich muss das Scheitern selber implementieren.
*verzweifel*
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 21:39
von BlackJack
@Strawk: Du weisst alles was man braucht. Wie ``if`` funktioniert, wie man eine Ausnahme auslöst, und welche Funktion man zum Testen auf Typen benutzt. Bis auf das ``if`` haben wir alles gezeigt was man braucht.
Edit: So sähe es übrigens mit `singledispatch()` aus:
Code: Alles auswählen
from __future__ import absolute_import, division, print_function
try:
from functools import singledispatch
except ImportError:
from singledispatch import singledispatch
@singledispatch
def nested_sum(item):
raise TypeError('unexpected value of type {0.__name__}'.format(type(item)))
def identity(item):
return item
nested_sum.register(int, identity)
try:
nested_sum.register(long, identity)
except NameError:
pass # Python >2 has no `long` type anymore.
@nested_sum.register(list)
def _(items):
return sum(nested_sum(item) for item in items)
def main():
print(nested_sum(42))
print(nested_sum([1, 2, [4711, 23], 42]))
print(nested_sum(1000000000000000000000000000000000000))
print(nested_sum(None))
if __name__ == '__main__':
main()
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 21:46
von kbr
Strawk hat geschrieben:Denn: Wenn y = 0 ist, wird x/y scheitern. l = 'willi' scheitert aber nicht; ich muss das Scheitern selber implementieren.
Genau. Wenn y = 0 ist, dann hast Du Glück. Die Ausnahme wirft sich von alleine. Manuell wird eine mit 'raise' geworfen. Nun mußt Du nur noch testen, wann das erforderlich sein soll, z.B. bei I = 'willi'. Eine klassische, häufig vorkommende Situation.
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 21:55
von Strawk
Code: Alles auswählen
def nested_sum(l):
try:
if not isinstance(l, list):
raise TypeError
except TypeError:
print 'no list'
i = 0
for e in l:
try:
if not isinstance(e, list):
raise TypeError
except TypeError:
print 'no list'
i1 = 0
for e1 in e:
try:
if not isinstance(e1, int):
raise TypeError
except TypeError:
print 'no integer'
i1 += e1
i += i1
return i
l = [['willi',2,2],[3,3,3],[4,4,4]]
print nested_sum(l)
Leider bekomme ich nicht 'meine' (die von mir selber definierten) Fehlermeldungen. Was ist falsch?
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 22:11
von __deets__
Ausnahmen auszulösen um sie dann sofort abzufangen ist sinnlos. Dann kannst du doch gleich ein print in den if Block packen.
Und auch wenn das jetzt kein schöner Code ist - eigentlich sollte es klappen. Was passiert denn?
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 22:18
von Strawk
Hallo!
Code: Alles auswählen
def nested_sum(l):
try:
if not isinstance(l, list):
raise TypeError
except TypeError:
return 'no list'
i = 0
for e in l:
try:
if not isinstance(e, list):
raise TypeError
except TypeError:
return 'no list'
i1 = 0
for e1 in e:
try:
if not isinstance(e1, int):
raise TypeError
except TypeError:
return 'no integer'
i1 += e1
i += i1
return i
l = [[2,2,2],[3,3,3],7]
print nested_sum(l)
l = [['willi',2,2],[3,3,3],[4,4,4]]
print nested_sum(l)
l = [[2,2,2],[3,3,3],[4,4,4]]
print nested_sum(l)
l = 'willi'
print nested_sum(l)
Ich bekam nicht meine eigenen Fehlermeldungen, sondern Sachen wie: "int is not iterable".
Hier eine hoffentlich bessere Version. Hat das Sinn, was ich gestrickt habe?
Grüße
Strawk
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 22:32
von BlackJack
@Strawk: Na das Problem ist wie schon gesagt das Du die Ausnahmen die Du auslöst auch gleich wieder ”behandelst” und zwar in dem Du eine Ausgabe mit `print()` machst, und dann der Code aber weitergeht als wenn die Ausnahme gar nicht da gewesen wäre.
Du willst doch eigentlich prüfen ob es sich um eine Liste handelt, und dann damit etwas bestimmtes machen, oder ob es sich um eine ganze Zahl handelt, und damit dann etwas bestimmtes machen, oder ob es weder Liste noch Zahl war, und *nur dann* einen `TypeError` auslösen. Den Liste und Zahl sind ja keine Fehler.
Ausserdem gehe ich mal ganz stark davon aus, das „nested list“ jede beliebige mögliche Verschachtelung meint, also beispielsweise auch ``[1, 2, [3, [4, 5]], 6, [[7]]]``. Und nicht nur etwas ”Zweidimensionales” wo nur auf der zweiten Ebene die Zahlen und nur Zahlen stehen.
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 22:52
von Alfons Mittelmeyer
Strawk hat geschrieben:Ich möchte eine Exeption vom Typ TypeError werfen (und fangen?)
Das Werfen ist einfach. Du machst einfach etwas, das nicht mit etwas Anderem als mit einer Integer geht, etwa:
Code: Alles auswählen
a = 3.5 # das ist keine Integer
a & 1 # und das geht dann nicht und wirft eine Exception
Und beim Fangen kommt es dann darauf an, was Du damit tun willst.
- Fangen, eine Fehlermeldung ausgeben und weitermachen
- Fangen, dazu noch eine Fehlermeldung ausgeben und abbrechen
Fall 1: Fangen, eine Fehlermeldung ausgeben und weitermachen
Code: Alles auswählen
a = 3.5
try:
a & 1
except TypeError:
print("Warum war das keine Integer, aber egal, ich mache weiter")
Fall 2: Fangen, dazu noch eine Fehlermeldung ausgeben und abbrechen
Code: Alles auswählen
a = 3.5
try:
a & 1
except TypeError:
print("Wieder keine Integer, ich gebe es jetzt endlich auf")
raise
Verständlich?
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Montag 15. Mai 2017, 23:11
von kbr
Des Nachts der Code-Troll sich befleißt
Ein jedes Thema an sich reißt
Die Funktionen leuchten weit und hell
Allein es stört der Coding-Smell.
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Dienstag 16. Mai 2017, 00:01
von Alfons Mittelmeyer
@Strawk: ich habe noch etwas vergessen. True und False zählen auch als Integer. Das solltre man auch noch abfangen:
Und genauso geht dann natürlich auch:
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Dienstag 16. Mai 2017, 06:28
von noisefloor
Hallo,
@Alfons Mittelmeyer
True und False zählen auch als Integer
Du musst ein anderes Python benutzen als alle anderen hier im Forum. Du musst. Kann gar nicht anders. Und streite da am besten erst gar nicht ab, dass macht's nur schlimmer.
Gruß, noisefloor
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Dienstag 16. Mai 2017, 10:07
von BlackJack
@noisefloor: Nee, das stimmt schon:
Code: Alles auswählen
In [1]: isinstance(True, int)
Out[1]: True
In [2]: isinstance(False, int)
Out[2]: True
In [3]: issubclass(bool, int)
Out[3]: True
In [4]: True + True
Out[4]: 2
In [5]: 42 / False
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-5-5e0a6f844f47> in <module>()
----> 1 42 / False
ZeroDivisionError: integer division or modulo by zero
In [6]: -True
Out[6]: -1
Da Vererbung eine „ist-ein(e)“-Beziehung ist, braucht man das aber nicht extra testen, denn `bool`-Werte *sind* `int`-Werte, also ist es okay das auch `True` und `False` addiert werden können, denn es sind ja (auch) ganze Zahlen.
Re: Bitte ein komplettes Beispiel für die TypeError-Exeption
Verfasst: Dienstag 16. Mai 2017, 14:50
von noisefloor
Hallo,
aha, ok. Wieder was gelernt. Mein Gedankengang war, dass bool ein eigener Datentyp ist. Bis zum subclassing hatte ich nicht gedacht.
@Alfons Mittelmeyer: wir nutzen doch das gleiche Python, sorry.
Gruß, noisefloor