Что такое значение None?


131

Я изучал Python и прочитал главу, в которой описывается его Noneценность, но, к сожалению, эта книга в некоторых моментах не очень ясна. Думал, что найду ответ на свой вопрос, если поделюсь им там.

Я хочу знать , что Noneзначение является и то , что вы используете это?

А еще я не понимаю эту часть книги:

Присвоение значения Noneпеременной - это один из способов вернуть ее в исходное пустое состояние.

Что это значит?

Ответы были отличными, хотя я не понимал большинство ответов из-за моего низкого знания компьютерного мира (я не знал о классах, объектах и ​​т. Д.). Что означает это предложение?

Присвоение значения Noneпеременной - это один из способов вернуть ее в исходное пустое состояние.

Финал:

Наконец, я получил свой ответ, глядя на разные ответы. Я должен ценить всех людей, которые потратили свое время, чтобы помочь мне (особенно Мартин Питерс и DSM), и я хотел бы выбрать все ответы как лучшие, но выбор ограничен одним. Все ответы были отличными.


39
Эта книга не слишком полезна; Noneне является пустым состоянием по умолчанию для переменных.
Мартейн Питерс

Вверху моей головы php - единственный язык, значение null которого эквивалентно пустому состоянию по умолчанию для переменной. Теперь мне интересно, какие еще языки это делают.
kojiro

@kojiro perl, хотя ни один из операторов равенства не любит сравнивать undef. также, возможно, javascript, хотя в нем есть nullи undefined.
Eevee

Значение по умолчанию для переменной javascript @kojiro - undefined, если оно не инициализировано.
thefourtheye

Верно, это отличается от того null, о чем я не могу сказать @MartijnPieters в его ответе.
kojiro

Ответы:


99

Ответ Мартейна объясняет, что Noneесть в Python, и правильно заявляет, что книга вводит в заблуждение. Поскольку программисты Python, как правило, никогда не скажут

Присвоение значения Noneпеременной - это один из способов вернуть ее в исходное пустое состояние.

Трудно объяснить, что имеет в виду Бриггс, так, чтобы это имело смысл и объясняло, почему никого здесь это не устраивает. Одна аналогия, которая может помочь:

В Python имена переменных похожи на наклейки, наклеенные на объекты. На каждой наклейке написано уникальное имя, и одновременно она может быть только на одном объекте, но при желании вы можете наклеить более одной наклейки на один и тот же объект. Когда ты пишешь

F = "fork"

вы наклеиваете наклейку «F» на строковый объект "fork". Если вы затем напишете

F = None

вы перемещаете наклейку на Noneобъект.

Бриггс просит вас представить, что вы не писали наклейку "F", на ней уже была Fнаклейка None, и все, что вы сделали, это переместили ее с Noneна "fork". Поэтому, когда вы печатаете F = None, вы «сбрасываете [ting] его в исходное, пустое состояние», если мы решили рассматривать его 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объекту.


1
извините, но что вы имеете в виду под Бриггсом? Вы имеете в виду автора этой книги? потому что его зовут Джейсон Р. Бриггс.
The_Diver

@The_Diver: да, это он.
DSM

Где я могу найти дополнительную информацию о встроенных именах Python?
The_Diver

3
Это отличное объяснение для непрограммиста. Большое спасибо!
Кристина

68

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это значение тоже, хотя тот , который часто используется для сигнала пустота. Книга, которую вы читаете, вводит в заблуждение в этом отношении.


1
Я думаю, что семантика пустоты отличается от семантики неопределенности . Поэтому я не уверен, что аналоги JavaScript и SQL проясняют ситуацию - они могут запутать проблему. В JavaScript есть как undefined и null .
kojiro

@kojiro: undefinedэто объект в JavaScript, и вы можете использовать этот объект явно, как и Noneв Python. Это сигнальный объект, имеющий почти то же значение.
Мартейн Питерс

@kojiro: SQL не является языком программирования, но NULLвсе же это то, что можно явно назначить и протестировать.
Мартейн Питерс

5
@MartijnPieters: SQL - это язык программирования, с очень конкретной целью, декларативным.
danielkza

3
@daniel: вопрос о том, квалифицируется ли SQL как язык программирования, был предметом долгих споров ... См. stackoverflow.com/questions/900055/…, чтобы узнать об интересных аспектах.
Мартин Питерс

23

Вот о чем говорится в документации PythonNone :

Единственное значение types.NoneType. Нет часто используется для обозначения отсутствия значения, например, когда аргументы по умолчанию не передаются в функцию.

Изменено в версии 2.4: присвоение значения None недопустимо и вызывает ошибку SyntaxError.

Примечание. Имена None и debug нельзя переназначить (присвоение им, даже имени атрибута, вызывает исключение SyntaxError), поэтому их можно рассматривать как «истинные» константы.

  1. Подтвердим тип Noneпервого

    print type(None)
    print None.__class__

    Вывод

    <type 'NoneType'>
    <type 'NoneType'>

По сути, NoneTypeэто такой же тип данных, как int, floatи т.д. Вы можете проверить список типов по умолчанию, доступных в Python в 8.15. types - Имена встроенных типов .

  1. И Noneэто экземпляр NoneTypeкласса. Так что мы можем захотеть создать экземпляры Noneсамих себя. Давай попробуем это

    print types.IntType()
    print types.NoneType()

    Вывод

    0
    TypeError: cannot create 'NoneType' instances

Итак, ясно, что нельзя создавать NoneTypeэкземпляры. Нам не нужно беспокоиться об уникальности стоимости None.

  1. Давайте проверим, как мы реализовали это Noneвнутри.

    print dir(None)

    Вывод

    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', 
     '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
     '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

За исключением того __setattr__, что все остальные атрибуты доступны только для чтения. Итак, мы не можем изменить атрибуты None.

  1. Попробуем добавить новые атрибуты в 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экземпляре.

  1. Давайте проверим, что происходит, когда мы что-то назначаем None. Согласно документации, он должен генерировать файл SyntaxError. Значит, если мы что-то присвоим None, программа вообще не будет выполняться.

    None = 1

    Вывод

    SyntaxError: cannot assign to None

Мы установили, что

  1. None это пример NoneType
  2. None не может иметь новых атрибутов
  3. Существующие атрибуты Noneнельзя изменить.
  4. Мы не можем создавать другие экземпляры NoneType
  5. Мы даже не можем изменить ссылку None, присвоив ей значения.

Итак, как уже упоминалось в документации, Noneдействительно может рассматриваться как true constant.

Счастливое знание None:)


Очень-очень интересно !! Одно сомнение в том, что использовать __setattr__для None
Grijesh Chauhan

9

Книга, на которую вы ссылаетесь, явно пытается значительно упростить смысл 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, значение которого неясно, и
  2. Наша функция может действительно нуждаться в обработке -1как обычном вводе.
>>> test(-1)
no x here

упс!

Таким образом, книга немного вводит в заблуждение, в основном, в своем использовании слова reset - присвоение 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

5

Другие ответы уже прекрасно объяснили значение 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'] , думая, что аргумент списка будет иметь значение по умолчанию [] при каждом вызове extendList.

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

Таким образом, list1 и list3 работают с одним и тем же списком по умолчанию, тогда как list2 работает с отдельным списком, который он создал (передав свой собственный пустой список в качестве значения для параметра списка).


«Нет» спаситель: (Измените пример выше, чтобы добиться желаемого поведения)

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


3

None - одноэлементный объект (имеется в виду только один None), используемый во многих местах языка и библиотеки для обозначения отсутствия какого-либо другого значения.


Например:
если dэто словарь, d.get(k)вернется, d[k]если он существует, но Noneесли у dнего нет ключа k.

Прочтите эту информацию из отличного блога: http://python-history.blogspot.in/


3

Все это хорошие ответы, но я думаю, что есть еще кое-что, чтобы объяснить, почему Noneэто полезно.

Представьте, что вы собираете приглашения на свадьбу. Вы хотите записать, будет ли присутствовать каждый человек. Если они присутствуют, вы устанавливаете person.attending = True. Если они не присутствуют, вы устанавливаете person.attending = False. Если вы не получили ответа, тогда person.attending = None. Таким образом вы сможете отличить отсутствие информации - None- от отрицательного ответа.


1

Я люблю примеры кода (а также фрукты), поэтому позвольте мне показать вам

apple = "apple"
print(apple)
>>> apple
apple = None
print(apple)
>>> None

Нет ничего не значит, это не имеет значения.

None оценивается как False.


8
print(None)печать .. None. Это делает не , как вы не предлагаете, печать ничего.
Мартин Питерс

REPL ничего не показывает, только Noneесли это результат последнего выражения. (что в основном полезно для функций, не предназначенных для возврата значения.)
Иви

Эх, моя ошибка, я использовал IDLE, и я предположил, что он печатает переменные, по-видимому, он использует repl. В настоящее время я использую SO, чтобы усовершенствовать свои собственные навыки чтения и понимания python / javascript / кода, поэтому я делаю некоторые ошибки :(
Азейра

2
IDLE, как и приглашение интерактивного интерпретатора Python, явно скрывает, None если это результат выражения, в основном, чтобы не загромождать вывод.
Мартин Питерс

-5
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 
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.