И причина выбора egg is Noneболее egg == None: Последние могут быть перегружены, и, вероятно, ломаются при сравнении действительного объекта None (зависит от того, как это реализовано, но не ожидает , что все взять сравнения с None во внимание, не так ли?) , при этом isвсегда работает одинаково.
94
почему разработчики Python просто не выбрали «ноль». Просто должен быть другим, не так ли? ;)
Видар
35
@ Vidar «None» - это не отсутствие объекта (как и «null», нулевая ссылка), это фактический объект. Вы никогда не получите объект None, передающий объект, который относится к какому-либо типу, отличному от NoneType. Это также не концепция языка. Она не встроена в язык Python, она является частью стандартной библиотеки Python. Нет! == (Гм) Null
Rushyo
11
@ naught101 Это бесполезно; так как нет понятия указателей. Если вы используете библиотеку ctypes, None будет использоваться в качестве синонима для нулевого адреса, но до сих пор нет языковой концепции «нулевой ссылки». В Python вы всегда оставляете ссылку на какой-либо объект, даже если этот объект имеет значение None. Я подозреваю, что это значительно упрощает язык.
Rushyo
5
отличная презентация, объясняющая «ошибку в миллиард долларов», которая является нулевым ref: infoq.com/presentations/… . Другими параметрами, отличными от null, являются Options или Maybe (custom) типы.
Майкл Троу
136
None, Питон ноль?
Там нет nullв Python, а есть None. Как уже говорилось, наиболее точный способ проверить, что что-то задано Noneв качестве значения, - это использовать isоператор тождества, который проверяет, что две переменные ссылаются на один и тот же объект.
Noneявляется единственным экземпляром класса, NoneTypeи любые дальнейшие попытки создания экземпляра этого класса будут возвращать тот же объект, который создает Noneодиночный объект . Новички в Python часто видят сообщения об ошибках, которые упоминают NoneTypeи задаются вопросом, что это такое. По моему личному мнению, эти сообщения можно просто назвать Noneпо имени, потому что, как мы скоро увидим, Noneмало места для неопределенности. Поэтому, если вы видите какое-то TypeErrorсообщение, в котором упоминается, что NoneTypeэто не может или не может, просто знайте, что это просто то None, что использовалось таким образом, что это невозможно.
Кроме того, Noneэто встроенная константа, и как только вы запускаете Python, ее можно использовать везде, будь то в модуле, классе или функции. NoneTypeнапротив, нет, вам нужно сначала получить ссылку на него, запросив Noneего класс.
>>>NoneTypeNameError: name 'NoneType'isnot defined
>>> type(None)NoneType
Вы можете проверить Noneуникальность с помощью функции идентичности Python id(). Он возвращает уникальный номер, присвоенный объекту, каждый объект имеет один. Если id двух переменных одинаков, то они фактически указывают на один и тот же объект.
В большинстве распространенных случаев результат будет таким же, но __eq__()метод открывает дверь, которая аннулирует любую гарантию точности, так как она может быть переопределена в классе для обеспечения особого поведения.
Рассмотрим этот класс.
>>>classEmpty(object):...def __eq__(self, other):...returnnot other
Таким образом, вы примеряете, Noneи это работает
>>> empty =Empty()>>> empty==NoneTrue
Но тогда это также работает на пустой строке
>>> empty==''True
И все еще
>>>''==NoneFalse>>> empty isNoneFalse
Случай 2: Использование Noneв качестве логического значения
Следующие два теста
if value:# do somethingifnot value:# do something
на самом деле оцениваются как
if bool(value):# do somethingifnot bool(value):# do something
Noneявляется "ложным", означающим, что если приведен к логическому значению, он вернется, Falseа если применяется notоператор, он вернется True. Обратите внимание, что это не уникальное свойство None. В дополнение к Falseсамому себе, свойство совместно используется пустыми списками, кортежами, наборами, комментариями, строками, а также 0 и всеми объектами из классов, которые реализуют __bool__()возвращаемый магический метод False.
>>> bool(None)False>>>notNoneTrue>>> bool([])False>>>not[]True>>>classMyFalsey(object):...def __bool__(self):...returnFalse>>> f =MyFalsey()>>> bool(f)False>>>not f
True
Поэтому при тестировании переменных следующим образом, будьте особенно внимательны к тому, что вы включаете или исключаете из теста:
def some_function(value=None):ifnot value:
value = init_value()
Выше вы хотели вызывать, init_value()когда значение установлено специально None, или вы имели в виду, что значение 0, или пустая строка, или пустой список также должны инициировать инициализацию. Как я уже сказал, будьте внимательны. Как это часто бывает в Python, явное лучше, чем неявное .
None на практике
None используется в качестве значения сигнала
Noneимеет особый статус в Python. Это любимое базовое значение, потому что многие алгоритмы рассматривают его как исключительное значение. В таких сценариях его можно использовать в качестве флага для обозначения того, что условие требует некоторой специальной обработки (например, установка значения по умолчанию).
Вы можете присвоить Noneключевым словам аргументы функции, а затем явно проверить ее.
def my_function(value, param=None):if param isNone:# do something outrageous!
Вы можете вернуть его по умолчанию при попытке получить доступ к атрибуту объекта, а затем явно проверить его, прежде чем делать что-то особенное.
value = getattr(some_obj,'some_attribute',None)if value isNone:# do something spectacular!
По умолчанию get()метод словаря возвращается Noneпри попытке доступа к несуществующему ключу:
>>> some_dict ={}>>> value = some_dict.get('foo')>>> value isNoneTrue
Если бы вы попытались получить к нему доступ, используя нижнюю нотацию, KeyErrorбыло бы поднято
>>> value = some_dict['foo']KeyError:'foo'
Точно так же, если вы пытаетесь вставить несуществующий элемент
>>> value = some_dict.pop('foo')KeyError:'foo'
который вы можете подавить с помощью значения по умолчанию, которое обычно устанавливается в None
value = some_dict.pop('foo',None)if value isNone:# 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 hereif value isNone:# do something here because the attribute was set to NoneexceptAttributeError:# 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 isNone:# do something here because 'some_key' is set to NoneexceptKeyError:# set a default
value =None# and do something because 'some_key' was missing# from the dict.
log_something(some_dict)
Два приведенных выше примера показывают, как обращаться с объектами и словарями, а как насчет функций? То же самое, но мы используем аргумент ключевого слова с двумя звездочками для этой цели:
def my_function(**kwargs):try:
value = kwargs['some_key']if value isNone:# do something because 'some_key' is explicitly # set to NoneexceptKeyError:# 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же, как в качестве сигнала. Создание часового в 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 =Noneif param2 is undefined:# we got nothing here either
log_something('param2 was missing')
param2 =None
С диктом
value = some_dict.get('some_key', undefined)if value isNone:
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 isNone:
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 различных объектов. Наконец, использование часового очень своеобразно. Часовой характерен для библиотеки, в которой он используется, и поэтому его область действия обычно должна быть ограничена внутренними компонентами библиотеки. Это не должно "вытекать" наружу. Внешний код должен узнавать об этом только в том случае, если их целью является расширение или дополнение API библиотеки.
Ах, так что IIUC, который обычно все равно будет звонить .__ eq__? В этом случае я отказываюсь от своего предложения.
hkBst
@MichaelEkoka вы можете поделиться источником этой впечатляющей и полезной информации.
Анидхья Бхатнагар
Общепринятая практика. Вы можете найти некоторые намеки на это , ознакомившись с руководством по Python , но чтение исходного кода популярных проектов - это мой совет номер один, чтобы быстро погрузиться в идиоматический Python .
Майкл
67
Это не называется нулевым, как на других языках, но None. Всегда есть только один экземпляр этого объекта, так что вы можете проверить эквивалентность с помощью x is None(сравнения идентификаторов) вместо x == None, если хотите.
Я собираюсь найти способ сломать Python путем повторного создания экземпляра None. Тогда победят все умные люди, которые сравнивают друг с NoneTypeдругом!
Zenexer
28
В Python для представления отсутствия значения вы можете использовать значение None ( types.NoneType.None ) для объектов и "" (или len () == 0 ) для строк. Следовательно:
if yourObject isNone:# if yourObject == None:...if yourString =="":# if yourString.len() == 0:...
Что касается разницы между "==" и "is", проверки на идентичность объекта с использованием "==" должно быть достаточно. Однако, поскольку операция «is» определяется как операция идентификации объекта, вероятно, более правильно использовать ее, а не «==». Не уверен, что есть даже разница в скорости.
Насколько я знаю, (0 == false) возвращает истину на КАЖДОМ языке программирования. Это потому, что false кодируется как 0, а «true» - как все, что НЕ 0. Однако, пожалуйста, обратите внимание, что оператор «is» не совпадает с оператором «==». Это более или менее одинаковая разница между "==" и "равно" в Java. Оператор «is» действительно проверяет, являются ли ДВА ОБЪЕКТА одинаковыми (один и тот же экземпляр, а НЕ одно и то же содержимое)!
Паоло Ровелли
12
Paolo, FYI, (0 == false) не возвращает true во всех языках программирования. Примером быстрого счетчика будет Scala, где (0 == false) возвращает false, и я уверен, что Scala не единственный язык программирования, который возвращает false при сравнении числа с логическим значением.
Роб Уилтон
2
Хорошо понял! Тогда, скажем, в большинстве языков программирования.
Паоло Ровелли
3
В JavaScript причина 0 == falseвозврата в trueтом, что оператор двойного равенства выполняет приведение типов. Однако с оператором тройного равенства 0 === falseвозвращается false, потому что «число» и «логическое значение» - это разные типы.
jkdev
1
@PaoloRovelli, в Lua, Ruby и Clojure, 0 обрабатывается как trueв условных выражениях . В Rust and Go 0и false есть разные типы, которые нельзя сравнивать на равенство.
скутер болтаться
0
Null - это особый тип объекта, такой как:
>>>type(None)<class'NoneType'>
Вы можете проверить, находится ли объект в классе 'NoneType':
>>>variable =None>>>variable isNoneTrue
Более подробная информация доступна на Python Docs
Нет не будет Это выражение будет возвращаться Trueдля любого ложного значения, а не только None.
insert_name_here
Правда, и простое «если не foo:» не ответит правильно на исходный вопрос, как указано. Тем не менее, Python динамически типизирован и предлагает сократить синтаксические протоколы, поэтому мне кажется правильным рассмотреть более простые, похожие конструкции.
egg is None
болееegg == None
: Последние могут быть перегружены, и, вероятно, ломаются при сравнении действительного объекта None (зависит от того, как это реализовано, но не ожидает , что все взять сравнения с None во внимание, не так ли?) , при этомis
всегда работает одинаково.None
, Питон ноль?Там нет
null
в Python, а естьNone
. Как уже говорилось, наиболее точный способ проверить, что что-то заданоNone
в качестве значения, - это использоватьis
оператор тождества, который проверяет, что две переменные ссылаются на один и тот же объект.Основы
Есть и может быть только один
None
None
является единственным экземпляром класса,NoneType
и любые дальнейшие попытки создания экземпляра этого класса будут возвращать тот же объект, который создаетNone
одиночный объект . Новички в Python часто видят сообщения об ошибках, которые упоминаютNoneType
и задаются вопросом, что это такое. По моему личному мнению, эти сообщения можно просто назватьNone
по имени, потому что, как мы скоро увидим,None
мало места для неопределенности. Поэтому, если вы видите какое-тоTypeError
сообщение, в котором упоминается, чтоNoneType
это не может или не может, просто знайте, что это просто тоNone
, что использовалось таким образом, что это невозможно.Кроме того,
None
это встроенная константа, и как только вы запускаете Python, ее можно использовать везде, будь то в модуле, классе или функции.NoneType
напротив, нет, вам нужно сначала получить ссылку на него, запросивNone
его класс.Вы можете проверить
None
уникальность с помощью функции идентичности Pythonid()
. Он возвращает уникальный номер, присвоенный объекту, каждый объект имеет один. Если id двух переменных одинаков, то они фактически указывают на один и тот же объект.None
не может быть перезаписаноВ гораздо более старой версии Python (до 2.4) можно было переназначить
None
, но не больше. Даже в качестве атрибута класса или в пределах функции.Поэтому можно с уверенностью предположить, что все
None
ссылки одинаковы. Там нет "обычай"None
.Для проверки на
None
использованиеis
операторомПри написании кода у вас может возникнуть соблазн проверить на Единое, как это:
Или проверить на ложь, как это
Вы должны понимать последствия и то, почему это часто хорошая идея, чтобы быть явным.
Случай 1: проверка, если значение
None
зачем это
скорее, чем
Первый эквивалентен:
В то время как выражение
value==None
на самом деле применяется такесли значение действительно так,
None
то вы получите то, что ожидали.В большинстве распространенных случаев результат будет таким же, но
__eq__()
метод открывает дверь, которая аннулирует любую гарантию точности, так как она может быть переопределена в классе для обеспечения особого поведения.Рассмотрим этот класс.
Таким образом, вы примеряете,
None
и это работаетНо тогда это также работает на пустой строке
И все еще
Случай 2: Использование
None
в качестве логического значенияСледующие два теста
на самом деле оцениваются как
None
является "ложным", означающим, что если приведен к логическому значению, он вернется,False
а если применяетсяnot
оператор, он вернетсяTrue
. Обратите внимание, что это не уникальное свойствоNone
. В дополнение кFalse
самому себе, свойство совместно используется пустыми списками, кортежами, наборами, комментариями, строками, а также 0 и всеми объектами из классов, которые реализуют__bool__()
возвращаемый магический методFalse
.Поэтому при тестировании переменных следующим образом, будьте особенно внимательны к тому, что вы включаете или исключаете из теста:
Выше вы хотели вызывать,
init_value()
когда значение установлено специальноNone
, или вы имели в виду, что значение0
, или пустая строка, или пустой список также должны инициировать инициализацию. Как я уже сказал, будьте внимательны. Как это часто бывает в Python, явное лучше, чем неявное .None
на практикеNone
используется в качестве значения сигналаNone
имеет особый статус в Python. Это любимое базовое значение, потому что многие алгоритмы рассматривают его как исключительное значение. В таких сценариях его можно использовать в качестве флага для обозначения того, что условие требует некоторой специальной обработки (например, установка значения по умолчанию).Вы можете присвоить
None
ключевым словам аргументы функции, а затем явно проверить ее.Вы можете вернуть его по умолчанию при попытке получить доступ к атрибуту объекта, а затем явно проверить его, прежде чем делать что-то особенное.
По умолчанию
get()
метод словаря возвращаетсяNone
при попытке доступа к несуществующему ключу:Если бы вы попытались получить к нему доступ, используя нижнюю нотацию,
KeyError
было бы поднятоТочно так же, если вы пытаетесь вставить несуществующий элемент
который вы можете подавить с помощью значения по умолчанию, которое обычно устанавливается в
None
None
используется как флаг и действительное значениеВышеописанное использование
None
применяется, когда оно не считается допустимым значением, а больше похоже на сигнал сделать что-то особенное. Однако существуют ситуации, когда иногда важно знать, откудаNone
взялись, потому что, хотя он используется в качестве сигнала, он также может быть частью данных.Когда вы запрашиваете у объекта его атрибут с
getattr(some_obj, 'attribute_name', None)
возвратом,None
он не сообщает вам, был ли установлен атрибут, к которому вы пытались получить доступ,None
или он вообще отсутствовал в объекте. Та же самая ситуация при доступе к ключу из словаря, напримерsome_dict.get('some_key')
, вы не знаете,some_dict['some_key']
отсутствует ли или просто установленNone
. Если вам нужна эта информация, обычный способ справиться с этим - попытаться напрямую получить доступ к атрибуту или ключу изtry/except
конструкции:Аналогично с dict:
Два приведенных выше примера показывают, как обращаться с объектами и словарями, а как насчет функций? То же самое, но мы используем аргумент ключевого слова с двумя звездочками для этой цели:
None
используется только как действительное значениеЕсли вы обнаружите, что ваш код завален вышеуказанным
try/except
шаблоном, чтобы просто различатьNone
флаги иNone
данные, просто используйте другое тестовое значение. Существует шаблон, в котором значение, которое выходит за пределы набора допустимых значений, вставляется как часть данных в структуру данных и используется для контроля и проверки особых условий (например, границ, состояния и т. Д.). Такое значение называется часовым, и его можно использовать такNone
же, как в качестве сигнала. Создание часового в Python тривиально.Приведенный
undefined
выше объект является уникальным и не делает ничего из того, что может представлять интерес для программы, поэтому он является отличной заменойNone
флага. Применяются некоторые предостережения, подробнее об этом после кода.С функцией
С диктом
С объектом
Как я упоминал ранее, таможенные стражи идут с некоторыми оговорками. Во-первых, они не похожи на ключевые слова
None
, поэтому python их не защищает. Вы можете перезаписатьundefined
вышеизложенное в любое время, в любом месте модуля, в котором он определен, поэтому будьте осторожны с тем, как вы его используете и используете. Далее, экземпляр, возвращаемыйobject()
не одноэлементным, если вы сделаете этот вызов 10 раз, вы получите 10 различных объектов. Наконец, использование часового очень своеобразно. Часовой характерен для библиотеки, в которой он используется, и поэтому его область действия обычно должна быть ограничена внутренними компонентами библиотеки. Это не должно "вытекать" наружу. Внешний код должен узнавать об этом только в том случае, если их целью является расширение или дополнение API библиотеки.источник
Это не называется нулевым, как на других языках, но
None
. Всегда есть только один экземпляр этого объекта, так что вы можете проверить эквивалентность с помощьюx is None
(сравнения идентификаторов) вместоx == None
, если хотите.источник
None
. Тогда победят все умные люди, которые сравнивают друг сNoneType
другом!В Python для представления отсутствия значения вы можете использовать значение None ( types.NoneType.None ) для объектов и "" (или len () == 0 ) для строк. Следовательно:
Что касается разницы между "==" и "is", проверки на идентичность объекта с использованием "==" должно быть достаточно. Однако, поскольку операция «is» определяется как операция идентификации объекта, вероятно, более правильно использовать ее, а не «==». Не уверен, что есть даже разница в скорости.
В любом случае, вы можете взглянуть на:
источник
0 == false
возврата вtrue
том, что оператор двойного равенства выполняет приведение типов. Однако с оператором тройного равенства0 === false
возвращаетсяfalse
, потому что «число» и «логическое значение» - это разные типы.true
в условных выражениях . В Rust and Go0
иfalse
есть разные типы, которые нельзя сравнивать на равенство.Null - это особый тип объекта, такой как:
Вы можете проверить, находится ли объект в классе 'NoneType':
Более подробная информация доступна на Python Docs
источник
В соответствии со значением проверки Истины , None напрямую проверяется как FALSE, поэтому будет достаточно простейшего выражения:
источник
True
для любого ложного значения, а не толькоNone
.