Что такое значение None?
Я изучал Python, и я прочитал главу, которая описывает None
ценность, но, к сожалению, эта книга не очень ясна в некоторых моментах. Я думал, что найду ответ на свой вопрос, если поделюсь им там.
Я хочу знать, что None
ценность и для чего вы ее используете?
А также, я не понимаю эту часть книги:
Назначение значения
None
переменная - это один из способов вернуть ее в исходное пустое состояние.
Что это значит?
Ответы были великолепны, хотя я не понимал большинство ответов из-за своего низкого знания компьютерного мира (я не узнал о классах, объектах и т. Д.). Что означает это предложение?
Назначение значения
None
переменная - это один из способов вернуть ее в исходное пустое состояние.
Финал:
Наконец-то я получил ответ от просмотра разных ответов. Я должен ценить всех людей, которые вкладывают свое время, чтобы помочь мне (особенно Martijn Pieters и DSM), и я хотел бы, чтобы я мог выбрать все ответы как лучшие, но выбор ограничен одним. Все ответы были великолепны.
8 ответов
Ответ Мартейна объясняет, что None
в Python, и правильно утверждает, что книга вводит в заблуждение. Поскольку программисты на Python, как правило, никогда не скажут
Назначение значения
None
переменная - это один из способов вернуть ее в исходное пустое состояние.
Трудно объяснить, что Бриггс имеет в виду, так как это имеет смысл и объясняет, почему никто здесь не выглядит довольным этим. Одна аналогия, которая может помочь:
В Python имена переменных подобны наклейкам на объектах. Каждая наклейка имеет уникальное имя, написанное на ней, и она может быть только на одном объекте за раз, но вы можете разместить более одной наклейки на одном объекте, если хотите. Когда ты пишешь
F = "fork"
Вы помещаете наклейку "F" на строковый объект "fork"
, Если потом пишешь
F = None
Вы перемещаете наклейку в None
объект.
Бриггс просит вас представить, что вы не написали стикер "F"
уже был F
наклейка на None
и все, что вы сделали, это переместили его из None
в "fork"
, Поэтому, когда вы печатаете F = None
, вы "возвращаете его в исходное, пустое состояние", если мы решили обработать None
как смысл empty state
,
Я вижу, к чему он клонит, но это плохой способ. Если вы запустите Python и введите print(F)
, ты видишь
>>> print(F)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'F' is not defined
и это NameError
означает, что Python не распознает имя F
, потому что нет такой наклейки. Если бы Бриггс был прав и F = None
перезагружается F
в исходное состояние, то он должен быть там сейчас, и мы должны увидеть
>>> print(F)
None
как мы делаем после того, как мы печатаем F = None
и наклеить наклейку None
,
Так что это все, что происходит. В действительности, Python поставляется с некоторыми стикерами, уже прикрепленными к объектам (встроенными именами), но другие вы должны написать себе такими строками, как F = "fork"
а также A = 2
а также c17 = 3.14
, а затем вы можете прикрепить их на другие объекты позже (как F = 10
или же F = None
; все то же самое.)
Бриггс делает вид, что все возможные наклейки, которые вы, возможно, захотите написать, уже прикреплены к None
объект.
None
это просто значение, которое обычно используется для обозначения "пусто" или "здесь нет значения". Это сигнальный объект; он имеет значение только потому, что в документации Python сказано, что он имеет это значение.
В данном сеансе интерпретатора Python есть только одна копия этого объекта.
Если вы пишете функцию, и эта функция не использует явное return
заявление, None
вместо этого возвращается, например. Таким образом, программирование с помощью функций значительно упрощается; функция всегда что-то возвращает, даже если это только None
объект.
Вы можете проверить это явно:
if foo is None:
# foo is set to None
if bar is not None:
# bar is set to something *other* than None
Другое использование - дать необязательным параметрам для функций "пустое" значение по умолчанию:
def spam(foo=None):
if foo is not None:
# foo was specified, do something clever!
Функция spam()
имеет необязательный аргумент; если ты позвонишь spam()
без указания этого значения по умолчанию None
дается ему, что позволяет легко определить, была ли функция вызвана с аргументом или нет.
Другие языки имеют аналогичные понятия. SQL имеет NULL
; JavaScript имеет undefined
а также null
, так далее.
Обратите внимание, что в Python переменные существуют благодаря использованию. Вам не нужно сначала объявлять переменную, поэтому в Python нет действительно пустых переменных. Установка переменной в None
тогда это не то же самое, что установка пустого значения по умолчанию; None
это тоже значение, хотя оно часто используется для обозначения пустоты. Книга, которую вы читаете, вводит в заблуждение по этому вопросу.
Об этом говорит документация по Python None
:
Единственное значение types.NoneType. Ни один из них часто используется для представления отсутствия значения, например, когда аргументы по умолчанию не передаются в функцию.
Изменено в версии 2.4: назначения на None являются незаконными и вызывают ошибку SyntaxError.
Примечание. Имена None и debug не могут быть переназначены (присвоения им, даже в качестве имени атрибута, вызывают SyntaxError), поэтому их можно считать "истинными" константами.
Давайте подтвердим тип
None
первыйprint type(None) print None.__class__
Выход
<type 'NoneType'> <type 'NoneType'>
В принципе, NoneType
это тип данных так же, как int
, float
и т. д. Вы можете ознакомиться со списком типов по умолчанию, доступных в Python в 8.15. типы - имена для встроенных типов.
А также,
None
это примерNoneType
учебный класс. Таким образом, мы могли бы создать экземплярыNone
сами. Давай попробуем этоprint types.IntType() print types.NoneType()
Выход
0 TypeError: cannot create 'NoneType' instances
Так ясно, не может создать NoneType
экземпляров. Нам не нужно беспокоиться об уникальности стоимости None
,
Давайте проверим, как мы реализовали
None
внутренне.print dir(None)
Выход
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Кроме __setattr__
все остальные атрибуты доступны только для чтения. Таким образом, мы никак не можем изменить атрибуты None
,
Давайте попробуем добавить новые атрибуты
None
setattr(types.NoneType, 'somefield', 'somevalue') setattr(None, 'somefield', 'somevalue') None.somefield = 'somevalue'
Выход
TypeError: can't set attributes of built-in/extension type 'NoneType' AttributeError: 'NoneType' object has no attribute 'somefield' AttributeError: 'NoneType' object has no attribute 'somefield'
Вышеуказанные операторы выдают эти сообщения об ошибках соответственно. Это означает, что мы не можем создавать атрибуты динамически на None
пример.
Давайте проверим, что происходит, когда мы назначаем что-то
None
, Согласно документации, он должен броситьSyntaxError
, Это означает, что если мы назначим что-тоNone
программа не будет выполнена вообще.None = 1
Выход
SyntaxError: cannot assign to None
Мы установили, что
None
это примерNoneType
None
не может иметь новые атрибуты- Существующие атрибуты
None
не может быть изменено - Мы не можем создавать другие экземпляры
NoneType
- Мы даже не можем изменить ссылку на
None
присваивая ему значения.
Итак, как указано в документации, None
действительно может рассматриваться как true constant
,
Счастливое знание None
:)
Книга, на которую вы ссылаетесь, явно пытается значительно упростить значение None
, Переменные Python не имеют начального, пустого состояния - переменные Python связаны (только), когда они определены. Вы не можете создать переменную Python без указания значения.
>>> print(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> def test(x):
... print(x)
...
>>> test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test() takes exactly 1 argument (0 given)
>>> def test():
... print(x)
...
>>> test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in test
NameError: global name 'x' is not defined
но иногда вы хотите, чтобы функция означала разные вещи в зависимости от того, определена переменная или нет. Вы можете создать аргумент со значением по умолчанию None
:
>>> def test(x=None):
... if x is None:
... print('no x here')
... else:
... print(x)
...
>>> test()
no x here
>>> test('x!')
x!
Тот факт, что это значение является особенным None
значение не очень важно в этом случае. Я мог бы использовать любое значение по умолчанию:
>>> def test(x=-1):
... if x == -1:
... print('no x here')
... else:
... print(x)
...
>>> test()
no x here
>>> test('x!')
x!
... но имея None
вокруг дает нам два преимущества:
- Нам не нужно выбирать специальное значение, как
-1
чей смысл неясен, и - Нашей функции может потребоваться
-1
как нормальный вход.
>>> test(-1)
no x here
упс!
Таким образом, книга немного вводит в заблуждение, главным образом, в использовании слова " сброс" - назначение None
имя является сигналом для программиста, что это значение не используется или что функция должна вести себя по умолчанию, но для сброса значения в исходное неопределенное состояние вы должны использовать del
ключевое слово:
>>> x = 3
>>> x
3
>>> del x
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Другие ответы уже прекрасно объяснили значение None. Однако я все же хотел бы пролить больше света на этом примере.
Пример:
def extendList(val, list=[]):
list.append(val)
return list
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')
print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3
Теперь попробуйте угадать вывод списка выше. Ну, ответ на удивление, как показано ниже:
list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']
Но почему?
Многие ошибочно ожидают, что list1 будет равен [10], а list3 будет равен ['a'], думая, что аргумент списка будет установлен в значение по умолчанию [] каждый раз, когда вызывается exteList.
Однако на самом деле происходит то, что новый список по умолчанию создается только один раз, когда функция определена, и этот же список затем впоследствии используется всякий раз, когда extensionList вызывается без указания аргумента списка. Это связано с тем, что выражения в аргументах по умолчанию вычисляются при определении функции, а не при ее вызове.
Поэтомуlist1 и list3 работают с одним и тем же списком по умолчанию, тогда как list2 работает с отдельным списком, который он создал (передавая свой пустой список в качестве значения параметра list).
"Нет" спасителя: (Измените пример выше, чтобы получить желаемое поведение)
def extendList(val, list=None):
if list is None:
list = []
list.append(val)
return list
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')
print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3
С этой пересмотренной реализацией результат будет:
list1 = [10]
list2 = [123]
list3 = ['a']
Примечание - пример кредита на toptal.com
None - это одноэлементный объект (имеется в виду только один None), используемый во многих местах языка и библиотеки для представления отсутствия какого-либо другого значения.
Например:
если d
это словарь, d.get(k)
вернусь d[k]
если он существует, но None
если d
не имеет ключа k
,
Прочитайте эту информацию из отличного блога: http://python-history.blogspot.in/
Все это хорошие ответы, но я думаю, что есть еще кое-что, чтобы объяснить, почему None
Полезно.
Представьте, что вы собираете приглашения на свадьбу. Вы хотите записать, будет ли присутствовать каждый человек. Если они присутствуют, вы устанавливаетеperson.attending = True
. Если они не приходят, вы устанавливаетеperson.attending = False
. Если вы не получили ответа, тогдаperson.attending = None
. Таким образом, вы можете отличить отсутствие информации -None
- и отрицательный ответ.
Я люблю примеры кода (а также фрукты), поэтому позвольте мне показать вам
apple = "apple"
print(apple)
>>> apple
apple = None
print(apple)
>>> None
Ничто не значит ничего, это не имеет значения.
Никто не оценивает Ложь.
largest=none
smallest =none
While True :
num =raw_input ('enter a number ')
if num =="done ": break
try :
inp =int (inp)
except:
Print'Invalid input'
if largest is none :
largest=inp
elif inp>largest:
largest =none
print 'maximum', largest
if smallest is none:
smallest =none
elif inp<smallest :
smallest =inp
print 'minimum', smallest
print 'maximum, minimum, largest, smallest