нулевой объект в Python?

Как ссылаться на объект null в Python?

Решение

В Python объектом 'null' является синглтон None.

Лучший способ проверить объект на "неидентичность" - использовать оператор тождества is:

if foo is None:
    ...
Комментарии (10)

None, нуль в Python?

В Python нет понятия null, вместо него есть None. Как уже говорилось, самый точный способ проверить, что чему-то было присвоено значение None - это использовать оператор тождества is, который проверяет, что две переменные относятся к одному и тому же объекту.

>>> foo is None
True
>>> foo = 'bar' 
>>> foo is None
False

Основы

Существует и может существовать только одно None

None является единственным экземпляром класса NoneType, и любые дальнейшие попытки инстанцирования этого класса вернут тот же объект, что делает None синглтоном. Новички в Python часто видят сообщения об ошибках, в которых упоминается NoneType, и задаются вопросом, что это такое. Я лично считаю, что эти сообщения могли бы просто упоминать None по имени, потому что, как мы скоро увидим, None оставляет мало места для двусмысленности. Так что если вы увидите сообщение TypeError, в котором говорится, что NoneType не может делать то-то или то-то, знайте, что это просто один None был использован так, как он не может.

Кроме того, None - это встроенная константа, как только вы начинаете использовать Python, она доступна для использования отовсюду, будь то модуль, класс или функция. А NoneType, напротив, нет, вам придется сначала получить ссылку на него, запросив у None его класс.

>>> NoneType
NameError: name 'NoneType' is not defined
>>> type(None)
NoneType

Уникальность None можно проверить с помощью функции идентификации Python id(). Она возвращает уникальный номер, присвоенный объекту, у каждого объекта он свой. Если id двух переменных одинаков, то они указывают на один и тот же объект.

>>> NoneType = type(None)
>>> id(None)
10748000
>>> my_none = NoneType()
>>> id(my_none)
10748000
>>> another_none = NoneType()
>>> id(another_none)
10748000
>>> def function_that_does_nothing(): pass
>>> return_value = function_that_does_nothing()
>>> id(return_value)
10748000

None не может быть перезаписано.

В гораздо более старой версии Python (до 2.4) можно было переназначить None, но теперь нет. Даже в качестве атрибута класса или в пределах функции.

# In Python 2.7
>>> class SomeClass(object):
...     def my_fnc(self):
...             self.None = 'foo'
SyntaxError: cannot assign to None
>>> def my_fnc():
        None = 'foo'
SyntaxError: cannot assign to None

# In Python 3.5
>>> class SomeClass:
...     def my_fnc(self):
...             self.None = 'foo'
SyntaxError: invalid syntax
>>> def my_fnc():
        None = 'foo'
SyntaxError: cannot assign to keyword

Поэтому можно предположить, что все ссылки None одинаковы. Не существует "пользовательского" None.

Для проверки на None используйте оператор is.

При написании кода у вас может возникнуть соблазн проверить Noneness следующим образом:

if value==None:
    pass

Или проверить на ложность следующим образом

if not value:
    pass

Вы должны понимать последствия и почему часто полезно быть явным.

Случай 1: проверка, является ли значение None.

зачем это делать

value is None

, а не

value==None

Первый вариант эквивалентен:

id(value)==id(None)

Тогда как выражение value==None на самом деле применяется следующим образом

value.__eq__(None)

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

>>> nothing = function_that_does_nothing()
>>> nothing.__eq__(None)
True

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

Рассмотрим этот класс.

>>> class Empty(object):
...     def __eq__(self, other):
...         return not other

Вы пробуете его на None, и он работает.

>>> empty = Empty()
>>> empty==None
True

Но затем он также работает на пустой строке

>>> empty==''
True

И все же

>>> ''==None
False
>>> empty is None
False

Случай 2: Использование None в качестве булевой величины

Следующие два теста

if value:
    # do something

if not value:
    # do something

на самом деле оцениваются как

if bool(value):
    # do something

if not bool(value):
    # do something

None является "ложным", то есть при приведении к булеву значению он вернет False, а при применении оператора not вернет True. Заметьте, однако, что это свойство не является уникальным для None. Помимо самого False, это свойство разделяют пустые списки, кортежи, множества, dicts, строки, а также 0 и все объекты из классов, реализующих магический метод __bool__() для возврата False.

>>> bool(None)
False
>>> not None
True

>>> bool([])
False
>>> not []
True

>>> class MyFalsey(object):
...     def __bool__(self):
...         return False
>>> f = MyFalsey()
>>> bool(f)
False
>>> not f
True

Поэтому при тестировании переменных следующим образом будьте особенно внимательны к тому, что вы включаете или исключаете из теста:

def some_function(value=None):
    if not value:
        value = init_value()

В приведенном выше примере вы хотели вызвать init_value(), когда значение установлено в None, или вы имели в виду, что значение, установленное в 0, или пустая строка, или пустой список также должны вызвать инициализацию. Как я уже сказал, будьте внимательны. Как это часто бывает в Python явное лучше неявного.

None на практике.

None используется как сигнальное значение

None имеет особый статус в Python. Это любимое базовое значение, потому что многие алгоритмы рассматривают его как исключительное значение. В таких сценариях его можно использовать как флаг, сигнализирующий о том, что условие требует специальной обработки (например, установки значения по умолчанию).

Вы можете присвоить None аргументам ключевого слова функции и затем явно проверить его наличие.

def my_function(value, param=None):
    if param is None:
        # do something outrageous!

Вы можете вернуть значение по умолчанию при попытке получить атрибут объекта, а затем явно проверить его, прежде чем делать что-то особенное.

value = getattr(some_obj, 'some_attribute', None)
if value is None:
    # do something spectacular!

По умолчанию метод get() словаря возвращает None при попытке получить доступ к несуществующему ключу:

>>> some_dict = {}
>>> value = some_dict.get('foo')
>>> value is None
True

Если бы вы попытались получить доступ к нему, используя нотацию subscript, то возникла бы KeyError.

>>> value = some_dict['foo']
KeyError: 'foo'

Аналогично, если вы попытаетесь открыть несуществующий элемент

>>> value = some_dict.pop('foo')
KeyError: 'foo'

который можно подавить с помощью значения по умолчанию, которое обычно устанавливается в None

value = some_dict.pop('foo', None)
if value is None:
    # booom!

None используется и как флаг, и как допустимое значение

Описанные выше случаи использования None применяются, когда оно не считается допустимым значением, а скорее является сигналом для выполнения чего-то особенного. Однако бывают ситуации, когда иногда важно знать, откуда взялся None, потому что, хотя он используется как сигнал, он также может быть

Комментарии (5)

Он называется не null, как в других языках, а None. Всегда существует только один экземпляр этого объекта, поэтому при желании можно проверять эквивалентность с помощью x is None (сравнение тождества) вместо x == None.

Комментарии (1)

В Python для обозначения отсутствия значения можно использовать значение None (types.NoneType.None) для объектов и "" (или len() == 0) для строк. Поэтому:

if yourObject is None:  # if yourObject == None:
    ...

if yourString == "":  # if yourString.len() == 0:
    ...

Что касается разницы между "==" и "is", то проверки на идентичность объекта с помощью "==" должно быть достаточно. Однако, поскольку операция "is" определена как операция идентификации объекта, вероятно, правильнее использовать ее, а не "==". Не уверен, есть ли разница в скорости.

В любом случае, вы можете взглянуть на:

Комментарии (7)

За правду тестирования значение, 'Нет' напрямую тестов как ложные, так что простейшим выражением будет достаточно:

if not foo:
Комментарии (2)