it-swarm.com.de

Python `wenn x nicht None ist` oder` wenn nicht x None ist`?

Ich habe immer gedacht, dass die if not x is None -Version klarer ist, aber Googles Styleguide und PEP-8 verwenden beide if x is not None. Gibt es einen kleinen Leistungsunterschied (ich nehme nicht an), und gibt es einen Fall, in dem einer wirklich nicht passt (was den anderen zu einem klaren Gewinner für meinen Kongress macht)? *

* Ich beziehe mich auf einen Singleton und nicht nur auf None.

... um Singletons wie None zu vergleichen. Verwendung ist oder nicht.

651
orokusaki

Es gibt keinen Leistungsunterschied, da sie mit demselben Bytecode kompiliert werden:

Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
...    return x is not None
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> def g(x):
...   return not x is None
...
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

Stilistisch versuche ich, not x is y zu vermeiden. Obwohl der Compiler es immer als not (x is y) behandelt, könnte ein menschlicher Leser das Konstrukt als (not x) is y missverstehen. Wenn ich x is not y schreibe, gibt es keine Mehrdeutigkeit.

903

Der Styleguide von Google und Python ist die beste Vorgehensweise:

if x is not None:
    # Do something about x

Die Verwendung von not x kann zu unerwünschten Ergebnissen führen. Siehe unten:

>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0]         # You don't want to fall in this one.
>>> not x
False

Es könnte Sie interessieren, welche Literale in Python zu True oder False ausgewertet werden:

Bearbeiten für Kommentar unten:

Ich habe nur noch ein paar Tests gemacht. not x is None negiert x nicht zuerst und wird dann mit None verglichen. Tatsächlich scheint der Operator is eine höhere Priorität zu haben, wenn er auf diese Weise verwendet wird:

>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False

Daher ist not x is None meiner ehrlichen Meinung nach am besten zu vermeiden.

Weitere Bearbeitung:

Ich habe gerade weitere Tests durchgeführt und kann bestätigen, dass Bukzors Kommentar korrekt ist. (Zumindest konnte ich es nicht anders beweisen.)

Dies bedeutet, dass if x is not None das genaue Ergebnis als if not x is None hat. Ich stehe korrigiert. Vielen Dank, bukzor.

Meine Antwort bleibt jedoch bestehen: Verwenden Sie den herkömmlichen if x is not None. :]

170
Xavier Ho

Der Code sollte so geschrieben sein, dass er zuerst für den Programmierer und dann für den Compiler oder Interpreter verständlich ist. Das "ist nicht" -Konstrukt ähnelt eher dem Englischen als dem "nicht ist".

122
Mark Ransom

Die Antwort ist einfacher als die Leute sie machen.

In beiden Fällen gibt es keinen technischen Vorteil, und "x ist nicht y" ist das, was alle anderen verwenden, was es zum klaren Gewinner macht. Es ist egal, ob es "eher wie Englisch aussieht" oder nicht; Jeder verwendet es, was bedeutet, dass jeder Benutzer von Python - auch chinesische Benutzer, deren Sprache Python nicht so aussieht - es auf einen Blick versteht, wobei die etwas weniger verbreitete Syntax einige zusätzliche Gehirnzyklen in Anspruch nimmt zu analysieren.

Sei nicht anders, nur um anders zu sein, zumindest in diesem Bereich.

30
Glenn Maynard

Python if x is not None oder if not x is None?

TLDR: Der Bytecode-Compiler analysiert beide zu x is not None - verwenden Sie daher aus Gründen der Lesbarkeit if x is not None.

Lesbarkeit

Wir verwenden Python, weil wir Dinge wie menschliche Lesbarkeit, Benutzerfreundlichkeit und Korrektheit verschiedener Paradigmen der Programmierung gegenüber der Leistung schätzen.

Python optimiert die Lesbarkeit, insbesondere in diesem Zusammenhang.

Analysieren und Kompilieren des Bytecodes

Das notbindet schwächer als is, daher gibt es hier keinen logischen Unterschied. Siehe die Dokumentation :

Die Operatoren is und is not testen die Objektidentität: x is y ist genau dann wahr, wenn x und y dasselbe Objekt sind. x is not y ergibt den inversen Wahrheitswert.

Der is not ist speziell in der Python Grammatik als Verbesserung der Lesbarkeit für die Sprache vorgesehen:

comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'

Und so ist es auch ein einheitliches Element der Grammatik.

Natürlich wird es nicht gleich analysiert:

>>> import ast
>>> ast.dump(ast.parse('x is not None').body[0].value)
"Compare(left=Name(id='x', ctx=Load()), ops=[IsNot()], comparators=[Name(id='None', ctx=Load())])"
>>> ast.dump(ast.parse('not x is None').body[0].value)
"UnaryOp(op=Not(), operand=Compare(left=Name(id='x', ctx=Load()), ops=[Is()], comparators=[Name(id='None', ctx=Load())]))"

Aber dann übersetzt der Byte-Compiler tatsächlich den not ... is in is not:

>>> import dis
>>> dis.dis(lambda x, y: x is not y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> dis.dis(lambda x, y: not x is y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

Verwenden Sie aus Gründen der Lesbarkeit und der beabsichtigten Verwendung der Sprache is not.

Es nicht zu benutzen ist nicht klug.

27
Aaron Hall

Der Operator is not wird aus stilistischen Gründen dem Negieren des Ergebnisses von is vorgezogen. "if x is not None:" liest sich genauso wie Englisch, aber "if not x is None:" erfordert Verständnis für die Priorität des Operators und liest sich nicht so wie Englisch.

Wenn es einen Leistungsunterschied gibt, liegt mein Geld bei is not, aber dies ist mit ziemlicher Sicherheit nicht die Motivation für die Entscheidung, diese Technik zu bevorzugen. Dies wäre natürlich implementierungsabhängig. Da is nicht überschreibbar ist, sollte es trotzdem einfach sein, Unterscheidungen zu optimieren.

10
Mike Graham

Persönlich benutze ich

if not (x is None):

dies wird von jedem Programmierer sofort und ohne Mehrdeutigkeit verstanden, auch von jenen, die sich nicht mit der Python -Syntax auskennen.

8
MikeTeX

if not x is None ähnelt eher anderen Programmiersprachen, aber if x is not None klingt für mich definitiv klarer (und ist grammatikalisch korrekter in Englisch).

Das heißt, es scheint mir eher eine Präferenz zu sein.

2
Davy8

Ich würde die besser lesbare Form x is not y vorziehen, als ich darüber nachdenken würde, wie man schließlich die Vorrangstellung der Operatoren für die Codebehandlung schreibt, um viel besser lesbaren Code zu erzeugen.

0
stefanogreg