2 Stimmen

Python OO: wie man den Verfahrensablauf in einer gesamten Klasse mit der `return`-Anweisung stoppt?

Wenn ich diesen Code ausführe:

from nltk import NaiveBayesClassifier,classify
import USSSALoader
import random

class genderPredictor():
......
......

Und self._loadNames() None zurückgibt, habe ich diesen Fehler erhalten (aus dem importierten Modul random):

shuffle C:\Python27\lib\random.py   285     
TypeError: object of type 'NoneType' has no len()

Dies ist passiert, weil trotzdem ich ein return Statement in getFeatures(self) gesetzt habe, der Ablauf in die nächste Klassenmethode springt (die trainAndTest(self, trainingPercent=0.80)) aufruft, die das random Modul aufruft (random.shuffle(featureset)).

Also möchte ich wissen: wie kann man den Prozedurfluss nicht nur in der Methode getFeatures(self), sondern in der gesamten Klasse, die sie enthält, stoppen?

Übrigens vielen Dank Stephen Holiday für das Teilen des Codes.

4voto

jdi Punkte 86608

Dies ist passiert, weil trotzdem ich ein Return-Statement in getFeatures(self) platziert habe, der Ablauf in die nächste Klassenmethode springt (die dann trainAndTest(self, trainingPercent=0.80) aufruft) und das random Modul aufruft (random.shuffle(featureset)).

Eine wichtige Sache, die man sich merken sollte, ist dass None ein absolut gültiger Wert ist. Das Return-Statement in Ihrem getFeatures() macht genau das, was es soll, und gibt den gültigen Wert zurück. Nur in einer Ausnahmesituation oder wenn Sie es explizit wollen, wird dieser Ablauf gestoppt.

Statt zu fragen, wie Sie "aus der Klasse herauskommen" können, sollten Sie überprüfen, ob die Rückgabewerte der Funktionen, die Sie aufrufen, das zurückgeben, was Sie erwarten, bevor Sie fortfahren. Es gibt zwei Stellen, an denen Sie das tun könnten:

def trainAndTest(self, trainingPercent=0.80):
    featureset = self.getFeatures()

...

def _loadNames(self):
    return USSSALoader.getNameList()

An der ersten Stelle könnten Sie überprüfen, ob if featureset is None ist, und entsprechend reagieren, falls es None ist.
An der zweiten Stelle könnten Sie anstatt blind zurückzugeben, zuerst überprüfen und dann reagieren.

Zweitens haben Sie die Möglichkeit, Ausnahmen zu erheben. Ausnahmen sind Situationen, in denen der Code auf einen Fehler gestoßen ist und nicht weitermachen kann. Dann liegt es in der Verantwortung der aufrufenden Funktion, es zu behandeln oder es an die übergeordnete Ebene weiterzuleiten. Wenn niemand die Ausnahme behandelt, wird Ihre Anwendung abgestürzt. Wie Sie sehen, wird eine Ausnahme aus der random-Klasse erhoben, weil Sie es zulassen, dass ein None-Wert in den shuffle-Aufruf gelangt.

names = USSSALoader.getNameList()
if names is None:
    # eine Ausnahme erheben?
    # etwas anderes tun?
    # den Benutzer um etwas bitten?

Die Frage in diesem Moment ist, was Ihre Anwendung in dem Moment tun soll, wenn sie anstelle einer gültigen Liste ein None erhält? Möchten Sie eine Ausnahme ähnlich derjenigen, die von random erhoben wird, aber hilfreicher und spezifischer für Ihre Anwendung? Oder möchten Sie einfach eine andere Methode aufrufen, die eine Standardliste zurückgibt? Ist das Fehlen der Namensliste überhaupt eine Situation, in der Ihre Anwendung etwas anderes als das Beenden tun kann? Das wäre eine nicht wiederherstellbare Situation.

names = USSSALoader.getNameList()
if names is None:
    raise ValueError("USSSALoader hat keine gültigen Namen zurückgegeben! Kann nicht fortsetzen!")

Aktualisierung

Aufgrund Ihres Kommentars wollte ich die spezifische Behandlung hinzufügen, die Sie wollten. Python hat einige eingebaute Ausnahmetypen, um verschiedene Umstände darzustellen. Diejenige, die Sie wahrscheinlich erheben möchten, ist IOError, was angibt, dass die Datei nicht gefunden werden konnte. Ich nehme an, dass "Datei" bedeutet, was auch immer die Datei ist, die USSSALoader.getNameList() verwenden muss und nicht finden kann.

names = USSSALoader.getNameList()
if names is None:
    raise IOError("Keine USSSALoader-Datei gefunden")

Zu diesem Zeitpunkt wird, sofern eine Funktion höher in der Aufrufkette es nicht behandelt, Ihr Programm mit einem Traceback-Fehler beendet werden.

0voto

Ned Batchelder Punkte 342778

Es gibt nichts so etwas wie "Rückkehr von der gesamten Klasse". Sie müssen Ihren Code so organisieren, dass Rückgabewerte in den Funktionen gültig sind, die sie erhalten. Diese Funktionen können den Wert testen, um zu bestimmen, was als nächstes zu tun ist. Die Klassengrenzen haben keinen Einfluss auf den Programmablauf, nur auf die Namensräume der Methoden.

0voto

Amber Punkte 473552

Allgemein würden Sie hier nach dem Aufruf der Funktion die Gültigkeit überprüfen, z. B.:

featureset = self.getFeatures()
if not featureset:
    # Sie könnten eine Fehlermeldung protokollieren, wenn Sie etwas erwartet haben, usw.
    return

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X