19 Stimmen

Null-Muster in Python zu wenig genutzt?

Hin und wieder stoße ich auf Code wie diesen:

foo = Foo()
...
if foo.bar is not None and foo.bar.baz == 42:
   shiny_happy(...)

Das erscheint mir, nun ja, unpythonisch.

In Objective-C können Sie Nachrichten an nil senden und als Antwort nil erhalten. Ich fand das schon immer ziemlich praktisch. Natürlich ist es möglich, eine Nullmuster in Python Nach den Ergebnissen zu urteilen, die mir Google liefert, scheint dies jedoch nicht sehr weit verbreitet zu sein. Warum ist das so?

Oder noch besser: Wäre es eine schlechte Idee, None.whatever None zurückgeben zu lassen, anstatt eine Ausnahme auszulösen?

3voto

Stefano Borini Punkte 132313

Ich glaube nicht, dass das eine gute Idee ist. Angenommen, Sie haben

foo.getValue()

Angenommen, getValue() gibt eine Zahl zurück, oder None wenn nicht gefunden. Nehmen wir nun an foo war kein Versehen oder ein Fehler. Infolgedessen würde es Folgendes zurückgeben None und machen Sie weiter, auch wenn es einen Fehler gibt.

Mit anderen Worten, Sie sind nicht mehr in der Lage zu unterscheiden, ob es keinen Wert gibt (gibt None ) oder wenn ein Fehler auftritt ( foo war None um damit zu beginnen). Sie ändern den Rückgabevertrag einer Routine mit einer Tatsache, die nicht der Kontrolle der Routine selbst unterliegt, und überschreiben damit möglicherweise deren Semantik.

2voto

danben Punkte 77356

Hier ist der Grund, warum ich das nicht für eine gute Idee halte:

foo = Foo() // now foo is None

// if foo is None, I want to raise an exception because that is an error condition.
// The normal case is that I expect a foo back whose bar property may or may not be filled in.
// If it's not filled in, I want to set it myself.

if not foo.bar // Evaluates to true because None.bar is None under your paradigm, I think
  foo.bar = 42 // Now what?

Wie würden Sie in diesem Fall vorgehen?

2voto

Virgil Dupras Punkte 2594

Ich stimme zwar mit anderen Antworten überein, die besagen, dass es gut ist, dass None eine Ausnahme macht, wenn nach einem Mitglied gefragt wird, ist dies ein kleines Muster, das ich manchmal verwende:

getattr(foo.bar, 'baz', default_value)

1voto

Woot4Moo Punkte 23471

Persönlich glaube ich, dass das Auslösen einer Ausnahme das ist, was passieren sollte. Nehmen wir an, Sie schreiben aus irgendeinem Grund eine Software für Raketen in Python. Stellen Sie sich die Atombombe vor und sagen wir, es gäbe eine Methode namens explode(timeToExplode) und timeToExplode wurde als None übergeben. Ich denke, Sie wären am Ende des Tages unglücklich, wenn Sie den Krieg verloren hätten, weil Sie das beim Testen nicht gefunden haben.

1voto

manifest Punkte 2118
foo = Foo()
...
if foo.bar is not None and foo.bar.baz == 42:
   shiny_happy(...)

Die obige Situation kann durch die Tatsache bereinigt werden, dass None zu False aufgelöst wird:

if foo.bar and foo.bar.baz == 42:
    shiny_happy(...)
else:
    not_happy(...)

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