нулевой объект в Python?
Как я могу ссылаться на нулевой объект в Python?
5 ответов
в Python объект "null" является одноэлементным None
.
лучший способ проверить вещи на "Noneness" - использовать оператор идентификации,is
:
if foo is None:
...
это не называется null, как в других языках, но None
. Всегда есть только один экземпляр этого объекта, поэтому вы можете проверить эквивалентность с x is None
(сравнение идентификаторов) вместо x == None
, Если вы хотите.
None
, Python null?
нет null
в Python вместо этого есть 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()
. Возвращает уникальный номер, присвоенный объект, у каждого объекта есть один. Если идентификатор двух переменных одинаков, то они фактически указывают на один и тот же объект.
>>> 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
является "falsey", что означает, что если в булевой он вернется False
и если использовать not
оператор он вернет True
. Обратите внимание, однако, что это не свойство, уникальное для None
. В дополнение к свойство является общим для пустых списков, кортежей, множеств, предсказывает, струны, а также 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
если вы попытаетесь получить к нему доступ, используя нотацию индекса a 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
пришел, потому что, хотя он используется в качестве сигнала, он также может быть частью данных.
при запросе объекта для его атрибут с getattr(some_obj, 'attribute_name', None)
вернуться None
не говорит вам, был ли атрибут, к которому вы пытались получить доступ, установлен в None
или если он вообще отсутствовал на объекте. Такая же ситуация при доступе к ключу из словаря, как some_dict.get('some_key')
, вы не знаете, если some_dict['some_key']
отсутствует или если он просто установлен в None
. Если вам нужна эта информация, обычный способ справиться с этим-напрямую попытаться получить доступ к атрибуту или ключу из try/except
конструкция:
try:
# equivalent to getattr() without specifying a default
# value = getattr(some_obj, 'some_attribute')
value = some_obj.some_attribute
# now you handle `None` the data here
if value is None:
# do something here because the attribute was set to None
except AttributeError:
# we're now hanling the exceptional situation from here.
# We could assign None as a default value if required.
value = None
# In addition, since we now know that some_obj doesn't have the
# attribute 'some_attribute' we could do something about that.
log_something(some_obj)
аналогично с dict:
try:
value = some_dict['some_key']
if value is None:
# do something here because 'some_key' is set to None
except KeyError:
# set a default
value = None
# and do something because 'some_key' was missing
# from the dict.
log_something(some_dict)
в приведенных выше двух примерах показано, как обрабатывать объектные и словарные случаи, как насчет функций? То же самое, но мы используем аргумент ключевого слова double asterisks для этого:
def my_function(**kwargs):
try:
value = kwargs['some_key']
if value is None:
# do something because 'some_key' is explicitly
# set to None
except KeyError:
# we assign the default
value = None
# and since it's not coming from the caller.
log_something('did not receive "some_key"')
None
используется только как допустимое значение
если вы обнаружите, что ваш код завален выше try/except
шаблон просто различать None
флаги и None
данные, затем просто используйте другое тестовое значение. Существует шаблон, в котором значение, которое выходит за пределы набора допустимых значений, вставляется как часть данных в структуру данных и используется для управления и тестирования специальных условий (например, границ, состояния и т. д.). Такое значение называется страж и его можно использовать путь None
используется в качестве сигнала. Тривиально создавать sentinel в Python.
undefined = object()
на undefined
объект выше уникален и ничего не делает это может представлять интерес для программы, поэтому это отличная замена для None
как флаг. Некоторые предостережения применяются, больше об этом после кода.
с функцией
def my_function(value, param1=undefined, param2=undefined):
if param1 is undefined:
# we know nothing was passed to it, not even None
log_something('param1 was missing')
param1 = None
if param2 is undefined:
# we got nothing here either
log_something('param2 was missing')
param2 = None
с dict
value = some_dict.get('some_key', undefined)
if value is None:
log_something("'some_key' was set to None")
if value is undefined:
# we know that the dict didn't have 'some_key'
log_something("'some_key' was not set at all")
value = None
с объектом
value = getattr(obj, 'some_attribute', undefined)
if value is None:
log_something("'obj.some_attribute' was set to None")
if value is undefined:
# we know that there's no obj.some_attribute
log_something("no 'some_attribute' set on obj")
value = None
как я уже упоминал ранее пользовательские часовые приходят с некоторыми оговорками. Во-первых, это не такие ключевые слова, как None
, поэтому python не защищает их. Вы можете перезаписать свой undefined
выше время, в любом месте модуля он определен, поэтому будьте осторожны, как вы их выставляете и используете. Затем экземпляр возвращается object()
не является синглтоном, если вы сделаете этот вызов 10 раз, вы получите 10 различных объектов. Наконец, использование sentinel очень своеобразно. Страж специфичен для библиотеки, в которой он используется, и поэтому его область обычно должна быть ограничена внутренними элементами библиотеки. Это не должно "просочиться". Внешний код должен только узнать об этом, если их цель-расширить или дополните API библиотеки.
в Python, чтобы представить отсутствие значения, вы можете использовать нет значение (типы.NoneType.Нет!--3-->) для объектов и "" (или len () = = 0) для строк. Таким образом:
if yourObject is None: # if yourObject == None:
...
if yourString == "": # if yourString.len() == 0:
...
Что касается разницы между "==" и "is", тестирование идентичности объекта с использованием "==" должно быть достаточным. Однако, поскольку операция " is " определяется как операция идентификации объекта, вероятно, правильнее использовать ее, а не "==". Не уверен, есть ли разница в скорости.
в любом случае, вы можете посмотреть на:
- Python встроенные константы страница doc.
- Python Правда Стоимость Тестирования страница doc.
Per правда стоимость тестирования,' None ' напрямую проверяет как FALSE, поэтому достаточно самого простого выражения:
if not foo: