Python `якщо x - немає None` або` if not x є None`?


745

Я завжди вважав, що if not x is Noneверсія буде більш зрозумілою, але обидва посібники зі стилю Google та PEP-8 використовують if x is not None. Чи є якась незначна різниця в продуктивності (я припускаю, що це не так), і чи є випадки, коли один насправді не підходить (що робить іншого явним переможцем для моєї конвенції)? *

* Я маю на увазі будь-яку одиночку, а не просто None.

... для порівняння одиночних кнопок, як Ніхто. Використовувати є чи ні.


8
is not- це оператор сам по собі. Як !=. Якщо ви віддаєте перевагу , not x is Noneто вам слід також віддати перевагу not a == bбільш a != b.
Томаш Гандор

@TomaszGandor Я більше не маю такої думки щодо not x is None(відповіді тут мене переконували) - однак, варто відзначити, що not a == bце кращий стиль у Python, порівняно з a != b.
орокусакі

4
@orokusaki - це not a == bсправді кращий стиль? Я ніколи не бачив, щоб це було зроблено саме так і скрізь, де я дивлюся, що люди використовують !=.
Майк - SMT

2
відліки читання @orokusaki В Python , так що це кращий стиль , щоб використовувати один оператор !=замість двох операторів not, ==.
Jeyekomon

Відповіді:


994

Немає різниці в продуктивності, оскільки вони компілюються в один і той же байт-код:

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

Стилістично я намагаюся уникати not x is y. Хоча компілятор завжди трактуватиме це так not (x is y), як людський читач може неправильно зрозуміти конструкцію як (not x) is y. Якщо я напишу, x is not yто двозначності немає.


103
Якщо тільки той самий людський читач не вважав це x is (not y). Але я схильний погоджуватися з вами з інших ваших міркувань.
Етаоін

24
до того ж "не" є менш неоднозначним у цьому контексті ", якщо" А "немає", "b" немає: "проти", якщо не "немає", "b" немає ",
Gordon Wrigley

45
оператор повинен бути "айн"
боб

216

Посібник зі стилів Google і Python - найкраща практика:

if x is not None:
    # Do something about x

Використання not xможе спричинити небажані результати.

Дивись нижче:

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

Можливо, вам буде цікаво подивитися, які літерали оцінюються на Trueабо Falseв Python:


Редагувати для коментаря нижче:

Я просто зробив ще кілька тестувань. not x is Noneне заперечує xспочатку, а потім порівняно з None. Насправді, здається, що isоператор має вищий пріоритет, коли використовується таким чином:

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

Тому not x is Noneпросто, на мою чесну думку, найкраще уникати.


Більше редагувати:

Я просто зробив більше тестування і можу підтвердити, що коментар bukzor правильний. (Принаймні, я не зміг довести це інакше.)

Це означає, що if x is not Noneмає точний результат if not x is None. Я стою виправлений. Дякую букзор.

Однак моя відповідь все ще стоїть: Використовуйте звичайнеif x is not None .:]


130

Код повинен бути написаний таким, щоб він був зрозумілий першому програмісту, а компілятору чи інтерпретатору - другим. Конструкція "не є" більше нагадує англійську, ніж "не є".


33

Пітон if x is not Noneабо if not x is None?

TLDR: Компілятор байт-коду аналізує їх обидва, так що x is not None- для зручності читання використовувати if x is not None.

Читабельність

Ми використовуємо Python, оскільки цінуємо такі речі, як читабельність людини, зручність використання та правильність різних парадигм програмування над продуктивністю.

Python оптимізує для читабельності, особливо в цьому контексті.

Розбір та компіляція байт-коду

У not пов'язує слабше , ніж is, так що немає ніякої логічної різниці тут. Дивіться документацію :

Оператори isі is notтест на ідентичність об'єкта: x is yістинно, якщо і лише тоді, коли x і y є одним і тим же об'єктом. x is not yдає зворотне значення істини.

is notСпеціально передбачено в Python граматиці як поліпшення читаності для мови:

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

А значить, це і єдиний елемент граматики.

Звичайно, він не розбирається однаково:

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

Але тоді компілятор байтів фактично переведе not ... isна 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

Тож заради читабельності та використання мови, як було призначено, будь ласка, використовуйте is not.

Не використовувати це не розумно.


" notПов'язується слабше is, тому немає логічної різниці тут" - за винятком того, що Python не повинен застосовувати логічні та алгебраїчні ідентичності, щоб утримувати (немає внутрішньої причини для того, (1 + 2)*3щоб оцінювати те саме, що 1*3 + 2*3). Тут, мабуть, Python обманює та оптимізує UNARY_NOT.
Олексій

30

Відповідь простіша, ніж люди це роблять.

Ні в якому разі немає технічної переваги, і "x не є" - це те, що використовують всі інші , що робить його явним переможцем. Не має значення, це "схоже на англійську" чи ні; всі користуються ним, а це означає, що кожен користувач Python - навіть китайські користувачі, мова яких Python не схожа - зрозуміють це з першого погляду, де трохи менш поширений синтаксис займе ще кілька додаткових мозкових циклів для розбору.

Не будьте різними лише заради того, щоб бути різними, принаймні в цій галузі.


11

is notОператор краще , ніж заперечує результат isпо стилістичним причин. " if x is not None:" читається так само, як англійська, але " if not x is None:" вимагає розуміння пріоритетності оператора і не читається як англійська.

Якщо є різниця у продуктивності, на мої гроші лежать is not, але це майже напевно не є мотивацією для рішення, щоб віддати перевагу цій техніці. Очевидно, це залежить від реалізації. Оскільки isце не можна перезаписати, то будь-яке розмежування має бути легко оптимізувати.


9

Особисто я використовую

if not (x is None):

що розуміється негайно без неоднозначності кожного програміста, навіть тих, хто не знає синтаксису Python.


5
Справедливий аргумент, з яким я згоден, але я вважаю, що аргумент слідування ідіоматичному стилю є сильнішим.
clacke

2

if not x is Noneбільше схожий на інші мови програмування, але, if x is not Noneбезумовно, звучить для мене більш чітко (і в англійській мові більш граматично правильний).

Це сказало, що здається, що це мені більше вподобано.


0

Я вважаю за краще більш читану форму, x is not y ніж я б думав, як в кінцевому підсумку написати перевагу обробки коду для операторів, щоб отримати набагато більше читабельного коду.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.