Python 'if X is not None' or`if not x is None'?

Zawsze myślałem o if not x is None wersja być bardziej jasne, ale style guide i PEP-8 oba używać if x is not None. Czy jest jakaś drobna różnica w wydajności (zakładam, że nie) i czy jest jakiś przypadek, w którym jedna naprawdę nie pasuje (czyniąc drugą wyraźnym zwycięzcą mojej konwencji)?*

*mam na myśli dowolny singleton, a nie tylko None.

...aby porównać singletony jak Brak Użycie jest lub nie jest.

Author: orokusaki, 2010-04-26

10 answers

Nie ma różnicy w wydajności, ponieważ kompilują się do tego samego bajtowego kodu:

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

Stylistycznie staram się unikać not x is y. Chociaż kompilator zawsze będzie traktował ją jako not (x is y), ludzki czytelnik może źle zrozumieć konstrukcję jako (not x) is y. Jeśli napiszę x is not y to nie ma dwuznaczności.

 800
Author: Daniel Stutzbach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-26 03:55:04

Zarówno Google jak i Python's style guide to najlepsza praktyka:

if x is not None:
    # Do something about x

Używanie {[3] } może powodować niepożądane rezultaty. Patrz poniżej:

>>> 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

Możesz być zainteresowany, aby zobaczyć, jakie literały są oceniane True lub False w Pythonie:

Edit for comment below:

Zrobiłem jeszcze kilka testów. not x jest None nie neguje x najpierw, a potem w porównaniu do None. W rzeczywistości wydaje się, że is operator ma wyższy priorytet, gdy jest używany w ten sposób:
>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False
Dlatego, moim zdaniem, najlepiej unikać.

Więcej edit:

Właśnie zrobiłem więcej testów i mogę potwierdzić, że komentarz bukzora jest poprawny. (Przynajmniej nie byłem w stanie udowodnić, że jest inaczej.)

Oznacza to, że if x is not None ma dokładny wynik jako if not x is None. Przyznaję się do błędu. Dzięki bukzor.

Jednak moja odpowiedź nadal pozostaje: użyj konwencjonalnego if x is not None. :]

 123
Author: Xavier Ho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 16:26:07

Kod powinien być napisany tak, aby był zrozumiały dla programisty po pierwsze, a kompilator lub interpreter po drugie. Konstrukcja "is not" przypomina język angielski bardziej niż "not is".

 113
Author: Mark Ransom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-26 03:15:55

Odpowiedź jest prostsza niż ludzie ją tworzą.

Nie ma żadnej przewagi technicznej, a "x to nie y" jest tym, co wszyscy inni używają , co czyni go wyraźnym zwycięzcą. Nie ma znaczenia, że "wygląda bardziej jak angielski", czy nie; wszyscy go używają,co oznacza, że każdy użytkownik Pythona-nawet użytkownicy chińscy, których język Python nie wygląda jak - zrozumie go na pierwszy rzut oka, gdzie nieco mniej popularna składnia zajmie kilka dodatkowych cykli mózgu, aby parse.

Nie bądź inny tylko po to, aby być innym, przynajmniej w tej dziedzinie.

 26
Author: Glenn Maynard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-26 07:18:03

Python if x is not None Czy if not x is None?

TLDR: kompilator kodu bajtowego parsuje je do {[5] } - więc dla dobra czytelności użyj if x is not None.

Czytelność

Używamy Pythona, ponieważ cenimy takie rzeczy jak ludzka czytelność, użyteczność i poprawność różnych paradygmatów programowania nad wydajnością.

Python optymalizuje czytelność, szczególnie w tym kontekście.

Parsowanie i kompilowanie kodu bajtowego

The not / align = "left" / słabo niż is, więc nie ma tu logicznej różnicy. Zobacz dokumentacja :

Operatory is i is not sprawdzają tożsamość obiektu: x is y jest prawdą wtedy i tylko wtedy, gdy X i y są tym samym obiektem. x is not y daje odwrotna wartość prawdy.

Język Python jest językiem, który nie jest językiem ojczystym, ale językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego jest językiem ojczystym, dla którego]}
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'

I tak jest to element unitarny gramatyki, jak również.

Oczywiście, to nie jest przetwarzane tak samo:

>>> 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())]))"

Ale wtedy kompilator bajtów faktycznie przetłumaczy not ... is na 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

Więc ze względu na czytelność i używanie języka zgodnie z przeznaczeniem, Proszę użyć is not.

Aby go nie używać nie jest mądrze.

 15
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-13 16:11:26

Operator is not jest preferowany zamiast negowania wyniku is ze względów stylistycznych. "if x is not None: "czyta się jak po angielsku, ale" if not x is None: " wymaga zrozumienia pierwszeństwa operatora i nie czyta się jak po angielsku.

Jeśli jest różnica w wydajności, moje pieniądze są na is not, ale to prawie na pewno nie jest motywacją do decyzji, aby preferować tę technikę. Byłoby to oczywiście zależne od wdrożenia. Ponieważ is nie jest overridable, powinno być łatwo zoptymalizować się jakiekolwiek rozróżnienie.

 8
Author: Mike Graham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-26 04:32:34

Osobiście używam

if not (x is None):

, który jest zrozumiany natychmiast bez dwuznaczności przez każdego programistę, nawet tych, którzy nie są znawcami składni Pythona.

 5
Author: MikeTeX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-26 16:14:23

if not x is None jest bardziej podobny do innych języków programowania, ale if x is not None zdecydowanie brzmi wyraźniej (i jest bardziej poprawny gramatycznie w języku angielskim).

To powiedziało, że wydaje mi się, że to bardziej rzecz preferencyjna.
 1
Author: Davy8,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-26 03:14:29

Wolałbym bardziej czytelną formę x is not y niż bym się zastanawiał, jak w końcu napisać kod obsługujący operatorów w celu wytworzenia kodu o wiele bardziej czytelnego.

 0
Author: stefanogreg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-24 07:19:34

Spróbuj tego:

    if x != None:
       # do stuff with x
 -3
Author: tylerswright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-16 15:06:19