¿Qué es un valor None?

130

He estado estudiando Python y leí un capítulo que describe el Nonevalor, pero desafortunadamente este libro no es muy claro en algunos puntos. Pensé que encontraría la respuesta a mi pregunta, si la comparto allí.

Quiero saber lo que el Nonevalor es y qué es lo que lo uso para?

Y también, no entiendo esta parte del libro:

Asignar un valor de Nonea una variable es una forma de restablecerlo a su estado vacío original.

Qué significa eso?

Las respuestas fueron geniales, aunque no entendí la mayoría de las respuestas debido a mi bajo conocimiento del mundo de la informática (no he aprendido sobre clases, objetos, etc.). ¿Qué significa esta oración?

Asignar un valor de Nonea una variable es una forma de restablecerlo a su estado vacío original.

Final:

Finalmente obtuve mi respuesta al buscar diferentes respuestas. Debo agradecer a todas las personas que dedicaron su tiempo a ayudarme (especialmente a Martijn Pieters y DSM), y deseo poder elegir todas las respuestas como las mejores, pero la selección se limita a una. Todas las respuestas fueron geniales.

The_Diver
fuente
39
Ese libro no es muy útil; Noneno es un estado vacío predeterminado para variables.
Martijn Pieters
Fuera de mi cabeza, php es el único lenguaje cuyo valor nulo es equivalente al estado vacío predeterminado para una variable. Ahora me pregunto qué otros idiomas hacen eso.
kojiro
@kojiro perl, aunque ninguno de los operadores de igualdad está contento con la comparación undef. también posiblemente javascript, aunque tiene ambos nully undefined.
Eevee
El valor predeterminado de la variable @kojiro javascript es undefined, si se deja sin inicializar.
thefourtheye
Correcto, que es diferente de null, un punto que no puedo hacer a @MartijnPieters en su respuesta.
kojiro

Respuestas:

99

La respuesta de Martijn explica lo que Nonehay en Python, y afirma correctamente que el libro es engañoso. Como los programadores de Python, por regla general, nunca dirían

Asignar un valor de Nonea una variable es una forma de restablecerlo a su estado vacío original.

Es difícil explicar lo que Briggs quiere decir de una manera que tenga sentido y explique por qué nadie aquí parece contento con eso. Una analogía que puede ayudar:

En Python, los nombres de las variables son como pegatinas colocadas en los objetos. Cada pegatina tiene un nombre único escrito, y solo puede estar en un objeto a la vez, pero puede poner más de una pegatina en el mismo objeto, si lo desea. Cuando escribes

F = "fork"

pones la pegatina "F" en un objeto de cuerda "fork". Si luego escribes

F = None

mueves la pegatina al Noneobjeto.

Lo que Briggs te pide que imagines es que no escribiste la pegatina "F", ya había una Fpegatina en el None, y todo lo que hiciste fue moverla , de Nonea "fork". Entonces, cuando escribe F = None, "lo restablece a su estado original y vacío", si decidimos tratarlo Nonecomo significado empty state.

Puedo ver a qué se dirige, pero esa es una mala manera de verlo. Si inicia Python y escribe print(F), verá

>>> print(F)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'F' is not defined

y eso NameErrorsignifica que Python no reconoce el nombre F, porque no existe dicha etiqueta . Si Briggs tenía razón y se F = Nonerestablece Fa su estado original, entonces debería estar allí ahora, y deberíamos ver

>>> print(F)
None

como lo hacemos después de escribir F = Noney poner la pegatina None.


Entonces eso es todo lo que está pasando. En realidad, Python viene con algunas pegatinas ya adheridas a los objetos (nombres incorporados), pero otras tienes que escribirlas con líneas como F = "fork"y A = 2y c17 = 3.14, y luego puedes pegarlas en otros objetos más tarde (como F = 10oF = None ; todo es lo mismo .)

Briggs finge que todas las etiquetas adhesivas posibles que desee escribir ya estaban pegadas al Noneobjeto.

DSM
fuente
1
lo siento, pero ¿qué quieres decir con Briggs? ¿te refieres al autor de este libro? porque se llama Jason R. Briggs.
The_Diver
@The_Diver: sí, ese es él.
DSM
¿Dónde puedo encontrar más información sobre los nombres integrados de Python? Gracias.
The_Diver
3
Esta es una gran explicación para un no programador. ¡Muchas gracias!
Christina
67

Nonees solo un valor que comúnmente se usa para indicar 'vacío' o 'sin valor aquí'. Es un objeto señal ; solo tiene significado porque la documentación de Python dice que tiene ese significado.

Solo hay una copia de ese objeto en una sesión de intérprete de Python dada.

Si escribe una función, y esa función no utiliza una returndeclaración explícita , Nonese devuelve, por ejemplo. De esa manera, la programación con funciones se simplifica mucho; una función siempre devuelve algo , incluso si es solo esaNone objeto.

Puedes probarlo explícitamente:

if foo is None:
    # foo is set to None

if bar is not None:
    # bar is set to something *other* than None

Otro uso es dar parámetros opcionales a las funciones por defecto 'vacío':

def spam(foo=None):
    if foo is not None:
        # foo was specified, do something clever!

La función spam()tiene un argumento opcional; si llama spam()sin especificarlo, Nonese le asigna el valor predeterminado , lo que facilita detectar si la función se llamó con un argumento o no.

Otros idiomas tienen conceptos similares. SQL tiene NULL; JavaScript tiene undefined y null , etc.

Tenga en cuenta que en Python, las variables existen en virtud de ser utilizadas. No necesita declarar una variable primero, por lo que no hay variables realmente vacías en Python. Establecer una variable en no Nonees lo mismo que establecerlo en un valor vacío predeterminado; Nonetambién es un valor, aunque uno que a menudo se usa para indicar el vacío. El libro que estás leyendo es engañoso en ese punto.

Martijn Pieters
fuente
1
Creo que la semántica del vacío es diferente de la de lo indefinido . Por lo tanto, no estoy seguro de que las contrapartes de JavaScript y SQL estén aclarando, pueden confundir el problema. JavaScript tiene ambos undefined y null .
kojiro
@kojiro: undefinedes un objeto en JavaScript, y puede usar ese objeto explícitamente al igual que Noneen Python. Es un objeto de señal, con el mismo significado.
Martijn Pieters
@kojiro: SQL no es un lenguaje de programación, pero NULLsigue siendo algo que puede asignarse y probarse explícitamente.
Martijn Pieters
55
@MartijnPieters: SQL es un lenguaje de programación, solo un propósito muy específico, declarativo.
danielkza
3
@daniel: si SQL califica como lenguaje de programación ha sido un largo debate ... Ver stackoverflow.com/questions/900055/… para ángulos interesantes.
Martijn Pieters
23

Esto es lo que la documentación de Python tiene que decir sobre None:

El único valor de los tipos.NoneType. Ninguno se usa con frecuencia para representar la ausencia de un valor, como cuando los argumentos predeterminados no se pasan a una función.

Cambiado en la versión 2.4: Las asignaciones a None son ilegales y generan un SyntaxError.

Nota Los nombres None y debug no se pueden reasignar (las asignaciones a ellos, incluso como nombre de atributo, aumentan SyntaxError), por lo que pueden considerarse constantes "verdaderas".

  1. Confirmemos el tipo de Noneprimero

    print type(None)
    print None.__class__

    Salida

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

Básicamente, NoneTypees un tipo de datos como int, floatetc. Puede consultar la lista de tipos predeterminados disponibles en Python en 8.15. tipos: nombres para los tipos integrados .

  1. Y, Nonees una instancia de NoneTypeclase. Por lo tanto, podríamos querer crear instancias de Nonenosotros mismos. Probemos eso

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

    Salida

    0
    TypeError: cannot create 'NoneType' instances

Claramente, no se pueden crear NoneTypeinstancias. No tenemos que preocuparnos por la unicidad del valor None.

  1. Veamos cómo lo hemos implementado Noneinternamente.

    print dir(None)

    Salida

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

Excepto __setattr__, todos los demás son atributos de solo lectura. Por lo tanto, no hay forma de que podamos alterar los atributos de None.

  1. Probemos y agreguemos nuevos atributos a None

    setattr(types.NoneType, 'somefield', 'somevalue')
    setattr(None, 'somefield', 'somevalue')
    None.somefield = 'somevalue'

    Salida

    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'

Las declaraciones vistas anteriormente producen estos mensajes de error, respectivamente. Significa que no podemos crear atributos dinámicamente en una Noneinstancia.

  1. Veamos qué sucede cuando asignamos algo None. Según la documentación, debe arrojar un SyntaxError. Significa que si le asignamos algo None, el programa no se ejecutará en absoluto.

    None = 1

    Salida

    SyntaxError: cannot assign to None

Hemos establecido que

  1. None es una instancia de NoneType
  2. None no puede tener nuevos atributos
  3. Los atributos existentes de Noneno se pueden cambiar.
  4. No podemos crear otras instancias de NoneType
  5. Ni siquiera podemos cambiar la referencia al Noneasignarle valores.

Entonces, como se menciona en la documentación, Nonerealmente se puede considerar como un true constant.

Feliz sabiendo None:)

thefourtheye
fuente
Muy muy interesante !! una duda de qué sirve __setattr__para Ninguno
Grijesh Chauhan
9

El libro al que se refiere está claramente tratando de simplificar enormemente el significado de None. Las variables de Python no tienen un estado inicial vacío: las variables de Python están vinculadas (solo) cuando se definen . No puede crear una variable de Python sin darle un valor.

>>> 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

pero a veces quieres que una función signifique cosas diferentes dependiendo de si una variable está definida o no. Puede crear un argumento con un valor predeterminado de None:

>>> def test(x=None):
...   if x is None:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

El hecho de que este valor sea el Nonevalor especial no es terriblemente importante en este caso. Podría haber usado cualquier valor predeterminado:

>>> def test(x=-1):
...   if x == -1:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

... pero tener Nonealrededor nos da dos beneficios:

  1. No tenemos que elegir un valor especial como -1cuyo significado no está claro, y
  2. Es posible que nuestra función necesite manejarse -1como una entrada normal.
>>> test(-1)
no x here

¡Uy!

Por lo tanto, el libro es un poco engañoso principalmente en su uso de la palabra restablecer : asignar Noneun nombre es una señal para un programador de que ese valor no se está utilizando o que la función debería comportarse de alguna manera predeterminada, sino restablecer un valor a su estado original e indefinido, debe usar la delpalabra clave:

>>> x = 3
>>> x
3
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
kojiro
fuente
5

Otras respuestas ya han explicado el significado de Ninguno maravillosamente. Sin embargo, todavía me gustaría arrojar más luz sobre esto usando un ejemplo.

Ejemplo:

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

Ahora intente adivinar la salida de la lista anterior. Bueno, la respuesta es sorprendentemente la siguiente:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

¿Pero por qué?

Muchos esperarán erróneamente que list1 sea ​​igual a [10] y list3 sea ​​igual a ['a'] , pensando que el argumento list se establecerá en su valor predeterminado de [] cada vez que se llame a extendList.

Sin embargo, lo que realmente sucede es que la nueva lista predeterminada se crea solo una vez cuando se define la función , y esa misma lista se usa posteriormente cada vez que se invoca extendList sin especificar un argumento de lista. Esto se debe a que las expresiones en los argumentos predeterminados se calculan cuando se define la función, no cuando se llama .

por lo tanto, list1 y list3 están operando en la misma lista predeterminada, mientras que list2 está operando en una lista separada que creó (pasando su propia lista vacía como el valor para el parámetro de lista).


'Ninguno' el salvador: (Modifique el ejemplo anterior para producir el comportamiento deseado)

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

Con esta implementación revisada, el resultado sería:

list1 = [10]
list2 = [123]
list3 = ['a']

Nota - Ejemplo de crédito a toptal.com

Jadav Bheda
fuente
3

None es un objeto singleton (lo que significa que solo hay un None), utilizado en muchos lugares del idioma y la biblioteca para representar la ausencia de algún otro valor.


Por ejemplo:
si des un diccionario, d.get(k)devolverá d[k]si existe, pero Nonesi dno tiene clave k.

Lea esta información de un gran blog: http://python-history.blogspot.in/

GrvTyagi
fuente
3

Todas estas son buenas respuestas, pero creo que hay más para explicar por qué Nonees útil.

Imagina que estás recogiendo RSVP para una boda. Desea registrar si asistirá cada persona. Si ellos asisten, tú pones person.attending = True. Si no están atendiendo tu set person.attending = False. Si no ha recibido ningún RSVP, entonces person.attending = None. De esa manera, puede distinguir entre ninguna información None, y una respuesta negativa.

Dab Brill
fuente
1

Me encantan los ejemplos de código (así como la fruta), así que déjame mostrarte

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

Ninguno significa nada, no tiene valor.

Ninguno se evalúa como Falso.

Azeirah
fuente
8
print(None)grabados .. None. Lo hace no , como usted sugiere, imprimir nada.
Martijn Pieters
REPL solo no muestra nada Nonesi es el resultado de la última expresión. (que es principalmente útil para las funciones que no están destinadas a devolver un valor).
Eevee
Eugh, mi error, estaba usando IDLE y supuse que imprimía variables, aparentemente usa repl. Actualmente estoy usando SO para perfeccionar mis propias habilidades de lectura y comprensión de python / javascript / código, así que estoy cometiendo algunos errores :(
Azeirah
2
IDLE, como el indicador del intérprete interactivo de Python, oculta explícitamente Nonesi ese es el resultado de una expresión, principalmente para no saturar la salida.
Martijn Pieters
-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 
Sree Latha
fuente