Python: если не val, vs, если val is None
Я всегда кодировался в стиле if not value
, однако несколько руководств привлекли мое внимание, что, хотя этот стиль работает, у него, похоже, есть две потенциальные проблемы:
- Это не вполне читаемо;
if value is None
, несомненно, более понятно.
- Это может иметь последствия позже (и вызывать тонкие ошибки), поскольку такие вещи, как
[]
и 0
, будут также оцениваться как False
.
Я также начинаю применять эту идею к другим сравнениям, например:
-
if not value
vs if value is False
-
if not value
vs if value is []
И вот список...
Вопрос в том, как далеко вы идете с принципом? Где рисовать линию, сохраняя ваш код в безопасности?
Должен ли я всегда использовать стиль if value is None
независимо от того, что?
Ответы
Ответ 1
Используйте сравнение с None, если это то, что вы хотите. Используйте "if not value", если вы просто хотите проверить, считается ли значение false (пустой список, none, false).
Я нахожу "если не значение" более чистым и питоническим.
Кроме того, будьте осторожны со списками. Вы не должны использовать это при сравнении для пустого списка. Если вы знаете, что получаете список, используйте "if", чтобы проверить, есть ли у него какое-либо содержимое (или len()). Попробуйте ввести это в интерпретатор:
>>> a = []
>>> a is []
False
Это связано с тем, что временный список, который вы только что создали, имеет другой адрес в памяти, чем тот, который хранится в 'a'. Вы не видите это с помощью None, False или True, потому что это все значения, которые являются синглонами (все они относятся к одному и тому же разделу памяти), поэтому используйте ключевое слово 'is'.
Вы также обнаружите, что внутристрочные строки CPython работают следующим образом.
>>> 'a' is 'a'
True
Вы не должны полагаться на это. Это деталь реализации, и это не указано для работы с каждой версией Python.
Ответ 2
Нет. Если вы хотите запустить код, когда значение ложно, но не None
, это будет ужасно.
Используйте is None
, если вы проверяете идентификатор с объектом None
. Используйте not value
, если вы хотите, чтобы значение было ложным.
Ответ 3
Ваше использование оператора is
немного проблематично. if value is []
всегда будет ложным, например, потому что ни один активный список не имеет одинакового идентификатора. Он отлично работает с None
, потому что None
является одноэлементным (все ссылки на None
являются одним и тем же объектом), но для других сравнений используйте ==
.
Однако if value
и if not value
отлично читаемы и полезны. IMHO нет необходимости быть более конкретным, если вам не нужно обрабатывать различные типы правдивых или ложных значений по-разному, например, различать 0 и None
.
Ответ 4
Мой ответ прост, поскольку он относится к большинству проблем кодирования: не пытайтесь написать что-то, что просто работает. Постарайтесь выразить свои намерения как можно более четко. Если вы хотите проверить, является ли значение ложным, используйте, if not value
. Если вы хотите проверить None
, запишите его. Это всегда зависит от ситуации и вашего суждения.
Вы не должны пытаться найти правила, которые можно применять, не задумываясь. Если вы найдете эти правила, это работа для компьютера, а не для человека! ;-)
Ответ 5
if not value:
pass
это хорошо и "pythonic". Это не вызывает тонких ошибок, правила явные и (я считаю) легко понять.
Если вам нужно провести различие между 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