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

746

Ich habe immer gedacht, dass die if not x is NoneVersion 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 eher auf einen Singleton als nur auf einen None.

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

Orokusaki
quelle
8
is notist ein eigenständiger Betreiber. Wie !=. Wenn Sie es vorziehen , not x is Nonedann sollte Ihr auch lieber not a == büber a != b.
Tomasz Gandor
@TomaszGandor Ich habe diese Meinung nicht mehr not x is None(die Antworten hier haben mich überzeugt) - es ist jedoch erwähnenswert, dass dies not a == bder bevorzugte Stil in Python im Vergleich zu ist a != b.
Orokusaki
4
@orokusaki ist not a == bwirklich der bevorzugte Stil? Ich habe es noch nie so gesehen und überall sehe ich Menschen, die alle benutzen !=.
Mike - SMT
2
@orokusaki In Python Lesbarkeit zählt , so dass es ein bevorzugter Stil ist einen Operator verwenden !=anstelle von zwei Operatoren not, ==.
Jeyekomon

Antworten:

995

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 zu vermeiden not x is y. Obwohl der Compiler es immer als behandelt not (x is y), kann ein menschlicher Leser das Konstrukt als falsch verstehen (not x) is y. Wenn ich schreibe, x is not ygibt es keine Mehrdeutigkeit.

Daniel Stutzbach
quelle
103
Es sei denn, derselbe menschliche Leser glaubte es x is (not y). Aber ich stimme Ihnen in Bezug auf Ihre anderen Überlegungen eher zu.
Etaoin
24
zusätzlich ist "ist nicht" in diesem Zusammenhang weniger mehrdeutig "wenn a nicht keine ist und b keine ist:" vs "wenn nicht a keine ist und b keine ist:"
Gordon Wrigley
45
Der Betreiber sollte "aint" sein
Bean
216

Der Styleguide von Google und Python ist die beste Vorgehensweise:

if x is not None:
    # Do something about x

Die Verwendung not xkann 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

Vielleicht interessiert es Sie, welche Literale für Trueoder Falsein Python ausgewertet werden :


Für Kommentar unten bearbeiten:

Ich habe nur noch ein paar Tests gemacht. not x is Nonenegiert nicht xzuerst und vergleicht dann mit None. Tatsächlich scheint der isOperator bei dieser Verwendung eine höhere Priorität zu haben:

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

Daher not x is Nonewird meiner ehrlichen Meinung nach nur am besten vermieden.


Weitere bearbeiten:

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

Dies bedeutet if x is not Nonedas genaue Ergebnis als if not x is None. Ich stehe korrigiert. Danke Bukzor.

Meine Antwort lautet jedoch weiterhin: Verwenden Sie das Konventionelleif x is not None .:]

Xavier Ho
quelle
131

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

Mark Ransom
quelle
33

Python if x is not Noneoder if not x is None?

TLDR: Der Bytecode-Compiler analysiert beide, x is not Noneum die Lesbarkeit zu verbessern if x is not None.

Lesbarkeit

Wir verwenden Python, weil wir Dinge wie die 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 not bindet schwächer als is, daher gibt es hier keinen logischen Unterschied. Siehe die Dokumentation :

Die Operatoren isund der is notTest auf Objektidentität: x is yist genau dann wahr, wenn x und y dasselbe Objekt sind. x is not yergibt den inversen Wahrheitswert.

Das is notist in der Python- Grammatik speziell als Lesbarkeitsverbesserung 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 das tatsächlich not ... isin 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

Um die Lesbarkeit zu verbessern und die Sprache so zu verwenden, wie sie beabsichtigt war, verwenden Sie bitte is not.

Es nicht zu benutzen ist nicht klug.

Aaron Hall
quelle
"Das notbindet schwächer als is, daher gibt es hier keinen logischen Unterschied" - außer dass Python keine logischen und algebraischen Identitäten erzwingen muss, um zu halten (kein wesentlicher Grund (1 + 2)*3, dasselbe zu bewerten wie 1*3 + 2*3). Hier betrügt und optimiert Python anscheinend UNARY_NOT.
Alexey
30

Die Antwort ist einfacher als die Leute es machen.

In beiden Fällen gibt es keinen technischen Vorteil, und "x ist nicht y" wird von allen anderen verwendet , was es zum klaren Gewinner macht. Es spielt keine Rolle, ob es "eher wie Englisch aussieht" oder nicht; Jeder verwendet es, was bedeutet, dass jeder Benutzer von Python - selbst chinesische Benutzer, deren Sprache Python nicht ähnelt - es auf einen Blick verstehen wird, wobei die etwas weniger verbreitete Syntax einige zusätzliche Gehirnzyklen zum Parsen benötigt.

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

Glenn Maynard
quelle
11

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

Wenn es einen Leistungsunterschied gibt, auf dem mein Geld liegt is not, ist dies mit ziemlicher Sicherheit nicht die Motivation für die Entscheidung, diese Technik zu bevorzugen. Es wäre offensichtlich implementierungsabhängig. Da ises nicht überschreibbar ist, sollte es sowieso einfach sein, eine Unterscheidung zu optimieren.

Mike Graham
quelle
9

Persönlich benutze ich

if not (x is None):

Dies wird von jedem Programmierer sofort verstanden, auch wenn er nicht mit der Python-Syntax vertraut ist.

MikeTeX
quelle
5
Ein faires Argument, dem ich zustimme, aber ich glaube, dass das Argument, dem idiomatischen Stil zu folgen, stärker ist.
Clacke
2

if not x is Noneist anderen Programmiersprachen ähnlicher, if x is not Noneklingt aber für mich definitiv klarer (und ist auf Englisch grammatikalisch korrekter).

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

Davy8
quelle
0

Ich würde die besser lesbare Form vorziehen, x is not y als ich mir vorstellen würde, wie man irgendwann die Priorität der Operatoren für die Codebehandlung schreibt, um viel besser lesbaren Code zu erzeugen.

stefanogreg
quelle