Как ссылаться на объект null в Python?
В Python объектом 'null' является синглтон None
.
Лучший способ проверить объект на "неидентичность" - использовать оператор тождества is
:
if foo is None:
...
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
Вы должны понимать последствия и почему часто полезно быть явным.
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
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
, потому что, хотя он используется как сигнал, он также может быть
Он называется не null, как в других языках, а None
. Всегда существует только один экземпляр этого объекта, поэтому при желании можно проверять эквивалентность с помощью x is None
(сравнение тождества) вместо x == None
.
В Python для обозначения отсутствия значения можно использовать значение None (types.NoneType.None) для объектов и "" (или len() == 0) для строк. Поэтому:
if yourObject is None: # if yourObject == None:
...
if yourString == "": # if yourString.len() == 0:
...
Что касается разницы между "==" и "is", то проверки на идентичность объекта с помощью "==" должно быть достаточно. Однако, поскольку операция "is" определена как операция идентификации объекта, вероятно, правильнее использовать ее, а не "==". Не уверен, есть ли разница в скорости.
В любом случае, вы можете взглянуть на:
За правду тестирования значение, 'Нет' напрямую тестов как ложные, так что простейшим выражением будет достаточно:
if not foo: