Methode return None und False

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.
Antworten
owR2K
User
Beiträge: 12
Registriert: Dienstag 28. April 2020, 10:32

Hallo,

meine Methode gibt ein json-Object zurück, wenn keine Daten vorhanden sind None und wenn es einen Fehler gab False.

Die Rückgabe von False scheint mit in dem Fall nicht optimal, es gibt aber keine andere Möglichkeit den dritten (Fehler-)Zustand an dem Rückgabewert zu erkennen?
Es wird dann ein ganz anderer Datentyp zurück gegeben, oder ist es von der Konform her besser immer beides per Tupel zu returnen?

Code: Alles auswählen

return: [object,boolean]
Löst immer aus, bei None und False:

Code: Alles auswählen

if not rückgabewert
Ich müsste dann explizit auf None und False prüfen:

Code: Alles auswählen

if rückgabewert is None

Code: Alles auswählen

if rückgabewert is False
Der Rückgabewert False wird nur zum prüfen der Funktionalität benötigt. In der Regel wird bei keinen Daten oder einen vorübergehenden Problem die aktuelle Operation ausgesetzt. Es reicht meistens also:

Code: Alles auswählen

if rückgabewert
VG
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Man prüft is None aber == False

Grundsätzlich macht man das aber nicht so. Um Fehler abzufangen gibt es in Python Exceptions. Die solltest du auch hier verwenden.
owR2K
User
Beiträge: 12
Registriert: Dienstag 28. April 2020, 10:32

@sparrow
In der entsprechenden Methode ist auch eine Exception.
Da das Programm aber nicht beendet werden soll, muss eine Rückgabe erfolgen nach dieser reagiert werden kann.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist quatsch. Wenn du an der Stelle des Aufrufs die Exception abfaengst, und dann im except-clause das tust, was du im Fehlerfall sonst auch tun wolltest, dann beendet sich da genau garnix.
Benutzeravatar
kbr
User
Beiträge: 1508
Registriert: Mittwoch 15. Oktober 2008, 09:27

@owR2K: der von dir gewünschte Programmablauf lässt sich in Python wie folgt umsetzen:

Code: Alles auswählen

try:
    rueckgabewert = get_rueckgabewert()
except TheExpectedException:
    handle_exception()
else:
    if rueckgabewert:
        do_something(rueckgabewert)
    else:
        do_something_else()
owR2K
User
Beiträge: 12
Registriert: Dienstag 28. April 2020, 10:32

Das bei except falls notwendig eine Aktion erfolgt ist natürlich sinnvoll.
Die Methode ist nur zum Abfragen von Daten, eine Exception in der Methode muss nichts machen außer eine Fehlermeldung ausgeben und einen speziellen Rückgabewert festlegen wenn das Programm weiter laufen soll. Die darüber gehenden Methoden reagieren auf die Rückgabe von None (keine Daten) entsprechend.

Eine zusätzliche Ausgabe von False würde ermöglichen keine Daten von einem Fehler zu unterscheiden. Diese Unterscheidung wäre wie gesagt nur für eine Test-Methode sinnvoll, welche mehrere solcher Methoden durch geht und dann ein abschließendes Ergebnis ausgibt. Wenn mehrere Methoden für einen Funktionstest geprüft werden sollen, kann eine Ausführung innerhalb einer einzelnen getesteten Methode & Exception dann nicht zielführend sein.

Ich hoffe das Problem ist damit klar ... vielleicht stehe ich ja auf dem Schlauch. :lol:
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Wie gesagt: Genau dafür sind Exceptions da. Dir wurde hier nun auch ein ausführluches Beispiel gezeigt, wir man mit try und except auf eine Exception reagiert, die in einer aufgerufenen Funktion auftritt (und eben nicht dort behandelt wird). Das macht man halt so. Dafür sind sie da. Da irgend etwas magisch in Rückgabewert zu kodieren ist halt falsch.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Eine Exception ermoeglicht, Daten von einem Fehler zu unterscheiden. Auch bei mehreren Methoden. Das ist also sehrwohl zielfuehrend. Die Diagnose lautet also leider Schlauchsteher ;)
owR2K
User
Beiträge: 12
Registriert: Dienstag 28. April 2020, 10:32

Naja, in dem Beispiel wird gezeigt wie bei einer Exception eine entsprechende Methode "handle_exception" ausgeführt wird. Das wird bei mir leider nicht benötigt, ich muss für den Test wissen, ob es in einer aufgerufenen Methode eine Exception gegeben hat.

Also hier ist die grobe Struktur:

Code: Alles auswählen

def daten_abruf_1():
	try:
		# abholen der Daten von externer Quelle
		# None wenn keine Daten
		return data
	except:
		print "error message"
		return False
		
def datenquellen_test():
	print ("Erreichbarkeits-Test der Datenquellen bei Programm-Initialisierung")
	daten_erreichbar = True
	if daten_abruf_1() == False:
		print ("Fehler beim Abrufen von Daten 1")
		daten_erreichbar = False
	if daten_abruf_2() == False:
		print ("Fehler beim Abrufen von Daten 2")
		daten_erreichbar = False
	if daten_erreichbar:
		print ("Einsatzbereit, Datenquellen sind erreichbar")
	return daten_erreichbar
	
def daten_verarbeiten():
	daten_1 = daten_abruf_1()
	
	if daten_1:
		#  ...
		return daten_bearbeitet
	return None

Vielleicht könnt ihr mir an dem Beispiel zeigen, wie lassen sich dann die Exceptions besser nutzen, damit so eine Methode "datenquellen_test" funktioniert (ohne return False)?

Wenn während der Laufzeit die Daten nicht erreichbar sind, gibt es nichts zu handeln außer eine entsprechende Meldung im Log, es kann eine kurzfristige nicht Erreichbarkeit sein. Aber beim Starten sollten die Daten natürlich erreichbar sein, sonst kann vielleicht ein Konfigurationsfehler vorliegen. Die Fehlermeldung der Exeption aus "daten_abruf_1" ist dann ebenfalls ein Hinweis auf das Problem.
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Man benutzt keine nackten ›except‹, sondern gibt die Exception immer konkret an, was man auch erwartet.
Beim `datenquellen_test` machst Du ja gar nichts mit den Daten.
Wenn in `daten_verarbeiten` es ok ist, dass daten_abruf einen Fehler meldet, dann None zurückgibt, dann kannst Du dort die Exception sinnvoll verarbeiten:

Code: Alles auswählen

def daten_abruf_1():
    # abholen der Daten von externer Quelle
    # None wenn keine Daten
    return data
        
def datenquellen_test():
    print("Erreichbarkeits-Test der Datenquellen bei Programm-Initialisierung")
    daten_erreichbar = True
    try:
        daten_abruf_1()
    except NichtErreichbar:
        print("Fehler beim Abrufen von Daten 1")
        daten_erreichbar = False
    try:
        daten_abruf_2()
    except NichtErreichbar:
        print("Fehler beim Abrufen von Daten 2")
        daten_erreichbar = False
    if daten_erreichbar:
        print("Einsatzbereit, Datenquellen sind erreichbar")
    return daten_erreichbar

    
def daten_verarbeiten():
    try:
        daten_1 = daten_abruf_1()
    except NichtErreichbar:
        print("Fehler beim Abrufen von Daten 1")
        return None
    else:
        #  ...
        return daten_bearbeitet
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei man auch beim abrufen der Daten eventuell schon überlegen kann entweder Daten zu liefern oder eine Ausnahme auszulösen statt einen Sonderwert `None` zu verwenden den man dann hier auch irgendwie wie einen Fehlerwert durch verschiedene Aufrufe durchschleift.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Oder, wenn die Daten eine Liste sind, bei "keine Daten" schlicht eine leere Liste zurück kommt - was wohl die natürlichste Form von "keine Daten" ist :)
Antworten