Когда я должен использовать None vs False? - PullRequest
2 голосов
/ 23 марта 2019

Из того, что я видел, None и False ведут себя по-разному только тогда, когда их сравнивают (для равенства).Я что-то упустил, или это нормально использовать только один или другой, если вы последовательны в своем использовании?Есть ли причина использовать один поверх другого?

Ответы [ 3 ]

5 голосов
/ 23 марта 2019

Я бы подчеркнул здесь семантическое различие, а не поведенческое.

Давайте рассмотрим пару функций:

def find_user(criteria):
    if is_met(criteria):
        return User(...)
    return None

# ...vs 

def has_email(user):
    return bool(user.email)

Для меня семантика None означает отсутствие значения, а семантика False означает логическую ложность.

Аналогией здесь может быть эволюция типа bool в C ++.Когда C (ab) использовал int для булевой логики, C ++ ввел выделенный тип bool, который проясняет намерения в отношении некоторых переменных / сигнатур функций.И это также допускает некоторые оптимизации, такие как std::vector<bool>, представленные внутри как вектор битов, а не байтов.

1 голос
/ 23 марта 2019

Они бывают разных типов.Хотя на практике они ведут себя совершенно одинаково.Вы также можете заменить False на: "", [], (,) или 0, и все будет работать в основном.Python автоматически преобразует вашу переменную в логическое значение, когда вы передаете ее if, while, любым логическим операторам (например, or, and и т. Д.) Или любой встроенной функции, ожидающей логическое значение (примечание: хотяor и and конвертируют ваше значение в логическое, решая, что возвращать, конечный результат будет вашим неконвертированным значением).Вот почему трудно различить разницу.

Однако большинство разработчиков считают, что None похоже на значение null в других языках, что является ошибкой или унифицированным значением.Whilist False обычно считается ожидаемым и полностью инициализированным значением.Поэтому большинству людей будет проще читать ваш код, если вы будете придерживаться этого соглашения.

Продолжая эту тему, давайте рассмотрим реализацию на языке Python.Типичный оператор if будет преобразован в инструкцию POP_JUMP_IF_FALSE (или POP_JUMP_IF_TRUE).Вот как это реализовано:

TARGET(POP_JUMP_IF_FALSE) {
    PyObject *cond = POP();
    int err;
    if (cond == Py_True) {
        Py_DECREF(cond);
        FAST_DISPATCH();
    }
    if (cond == Py_False) {
        Py_DECREF(cond);
        JUMPTO(oparg);
        FAST_DISPATCH();
    }
    err = PyObject_IsTrue(cond);
    Py_DECREF(cond);
    if (err > 0)
        ;
    else if (err == 0)
        JUMPTO(oparg);
    else
        goto error;
    DISPATCH();
}

Как вы можете видеть, если значение, переданное if, является логическим значением, интерпретатор будет знать, что делать немедленно.В противном случае он вызовет PyObject_IsTrue, который попытается преобразовать объект в логическое значение, используя любые возможные способы (__bool__, __nonzero__, __len__ и даже сравнение с None явно).

0 голосов
/ 23 марта 2019

Если вы проверяете, присвоено ли значение или существует, вы можете использовать None.

dct = {'key':'value'}
x = dct.get('key', None) # Get the value or get`None if it doesn't exist

def func(...):
   if condition:
      return Object()
   return None

Если вы знаете, что значение будет существовать, но хотите проверить его свойство, используйте False

if empty_list: #An empty list evaluates to `False`
   do something
if not bool_var:
   do something

Также bool(None) оценивается как False

...