Unterschied zwischen if obj und ob obj ist nicht None

8

Beim Schreiben eines XML-Parsing-Codes erhielt ich die Warnung:

%Vor%

Ich habe if <elem>: verwendet, um zu überprüfen, ob ein Wert für ein bestimmtes Element gefunden wurde.

Kann jemand den Unterschied zwischen if <obj>: und if <obj> is not None: näher erläutern und warum kümmert sich Python was ich benutze?

Ich benutze fast immer das erstere, weil es kürzer und nicht doppelt negativ ist, aber oft das Letztere im Quellcode anderer Leute sieht.

    
Dylan Hettinger 03.09.2013, 02:23
quelle

4 Antworten

8

if obj is not None Test, ob das Objekt nicht None ist. if obj prüft, ob bool(obj) True ist.

Es gibt viele Objekte, die nicht None sind, für die bool(obj) jedoch False ist: zum Beispiel eine leere Liste, ein leeres Dict, eine leere Menge, eine leere Zeichenfolge. . .

Verwenden Sie if obj is not None , wenn Sie testen möchten, ob ein Objekt nicht None ist. Verwenden Sie if obj nur, wenn Sie auf allgemeine "Falschheit" testen wollen - deren Definition objektabhängig ist.

    
BrenBarn 03.09.2013, 02:26
quelle
5

Diese Antwort adressiert speziell das FutureWarning.

Wenn lxml zum ersten Mal geschrieben wurde, wurde der lxml.etree._Element als falsch betrachtet, wenn er keine Kinder hatte.

Als Folge kann dies passieren:

%Vor%

lxml hat seit mehr als sieben Jahren versprochen, dass sich diese Änderung ereignen wird (nachdem wir mehrere Versionen durchgespielt haben), ist aber nie auf die Bedrohung gefolgt, ohne Zweifel wegen der zentralen Bedeutung von lxml und befürchtet, dass es viele brechen würde bestehender Code.

Um jedoch explizit und sicher zu sein, dass Sie keinen Fehler machen, verwenden Sie niemals if obj oder if not obj , wenn dieses Objekt den Typ lxml.etree._Element hat.

Verwenden Sie stattdessen eine der folgenden Prüfungen:

%Vor%     
Jordan Reiter 22.07.2014 17:20
quelle
1

Für eine vollständige Erklärung betrachten Sie das folgende Beispiel:

%Vor%

Was passiert in is_truthy() ? Lass es uns herausfinden. Wenn Sie dis.dis(is_truthy) ausführen, erhalten Sie:

%Vor%

Wie Sie sehen können x wird auf den Stack geschoben, dann wird POP_JUMP_IF_FALSE ausgeführt. Dies wird den Sprung zum ersten drücken und dann die richtige Antwort zurückgeben.

POP_JUMP_IF_FALSE ist in ceval.c definiert:

%Vor%

Wie Sie sehen, ist das von POP_JUMP_IF_FALSE konsumierte Objekt bereits entweder True oder False . Die Antwort ist einfach. Andernfalls versucht der Interpreter herauszufinden, ob das Objekt truthy ist, indem er PyObject_IsTrue() aufruft, was in Objektprotokoll . Der Code in object.c zeigt Ihnen genau, wie es funktioniert:

%Vor%

Auch wenn das Objekt nur True oder False selbst ist, ist die Antwort einfach. None wird ebenfalls als falsch angesehen. Dann verschiedene Protokolle wie das Nummernprotokoll , das Mapping-Protokoll und die Sequenz Protokoll werden überprüft. Ansonsten gilt das Objekt als wahr.

Um es zu beenden: x wird als wahr betrachtet, wenn es True ist, true entsprechend der Nummer, dem Mapping oder dem Sequenzprotokoll oder einer anderen Art von Objekt. Wenn Sie möchten, dass Ihr Objekt als falsch ausgewertet wird, können Sie dies tun, indem Sie eines der Protokolle implementieren, siehe die bereitgestellten Links.

Vergleichen mit None like in if x is None ist ein expliziter Vergleich. Die obige Logik gilt nicht.

    
user2722968 03.09.2013 06:36
quelle
0

Das Verhalten von if x ist irgendwie interessant:

%Vor%

So werden zum Beispiel Anweisungen unter der Bedingung if x nicht ausgeführt, wenn x 0, None, die leere Liste oder die leere Zeichenfolge ist. Auf der anderen Seite wird if x is not None nur dann angewendet, wenn x genau None ist.

    
sl8r000 03.09.2013 05:56
quelle

Tags und Links