Python: если не val, vs если val отсутствует - PullRequest
40 голосов
/ 22 августа 2011

Я всегда кодировал в стиле if not value, однако, несколько руководств обратили мое внимание на то, что хотя этот стиль работает, у него, похоже, есть 2 потенциальные проблемы:

  1. Этоне полностью читаемый;if value is None, безусловно, более понятен.
  2. Это может иметь последствия позже (и привести к незначительным ошибкам), поскольку такие вещи, как [] и 0, также оценятся в False.*

    Я также начинаю применять эту идею для других сравнений, таких как:

    • if not value против if value is False
    • if not value против if value is []

    И вот список ...

    Вопрос в том, как далеко вы продвинулись с принципом?Где провести черту, сохраняя при этом ваш код в безопасности?

    Должен ли я всегда использовать стиль if value is None, несмотря ни на что?

Ответы [ 5 ]

24 голосов
/ 22 августа 2011

Нет.Если вы хотите запустить код, когда значение равно false, но не равно None, это будет ужасно неудачно.

Используйте is None, если вы проверяете идентичность с объектом None.Используйте not value, если вы просто хотите, чтобы значение было False.

23 голосов
/ 23 августа 2011

Используйте сравнение с None, если вы этого хотите.Используйте «если не значение», если вы просто хотите проверить, считается ли значение ложным (пустой список, нет, ложь).

Я считаю, что «если не значение» выглядит чище и Pythonic.

Также будьте осторожны со списками.Вы не должны использовать это при сравнении для пустого списка.Если вы знаете, что получаете список, используйте «if», чтобы проверить, есть ли в нем содержимое (или len ()).Попробуйте ввести это в интерпретаторе:

>>> a = []
>>> a is []
False

Это потому, что только что созданный вами временный список имеет в памяти другой адрес, чем тот, который хранится в «a».Вы не видите этого с None, False или True, потому что все эти значения являются одиночными (все они относятся к одному и тому же разделу памяти), поэтому использование ключевого слова is работает.

также найдите, что CPython интернирует строки, поэтому работает следующее:

>>> 'a' is 'a'
True

Вы должны не полагаться на это.Это деталь реализации, и она не указана для работы с каждой версией Python.

4 голосов
/ 23 августа 2011

Использование оператора is немного проблематично. Например, if value is [] всегда будет ложным, поскольку никакие два активных списка не имеют одинаковую идентичность. Он отлично работает с None, потому что None является одиночным (все ссылки на None являются одним и тем же объектом), но для других сравнений используйте ==.

Однако if value и if not value отлично читаются и полезны. ИМХО, нет необходимости быть более конкретным, , если только вам не нужно по-разному относиться к различным типам истинных или ложных значений, как, например, различать 0 и None.

2 голосов
/ 22 августа 2011

Мой ответ прост, поскольку он относится к большинству проблем кодирования: не пытайтесь написать что-то, что просто работает. Постарайтесь выразить свои намерения как можно более четко. Если вы хотите проверить, является ли значение ложным, используйте if not value. Если вы хотите проверить на None, запишите его. Это всегда зависит от ситуации и вашего суждения.

Вы не должны пытаться найти правила, которые можно применять, не задумываясь. Если вы найдете эти правила, это работа для компьютера, а не для человека! ; -)

1 голос
/ 23 августа 2011
if not value:
    pass

хорошо и "питонно".Это не вызывает скрытых ошибок, правила явные и (я считаю) легко понять .

Если вам нужно различать False и None, как вы упомянули, используйте:

if not value is None:  # or False, or == [], etc.
    pass

# more readable
if value is not None:  # or False, or != [], etc.
    pass

Я считаю, что вышеупомянутое редко необходимо.

В общем, предпочтительнее ставить положительные условия и ставить их на первое место.Их легче понять с первого взгляда и они хорошо держатся при увеличении сложности (как это всегда кажется).

if value:
    pass
else:
    pass
...