Che cos'è un valore Nessuno?


130

Ho studiato Python e ho letto un capitolo che descrive il Nonevalore, ma sfortunatamente questo libro non è molto chiaro in alcuni punti. Ho pensato che avrei trovato la risposta alla mia domanda, se la condividessi lì.

Voglio sapere qual è il Nonevalore di è e ciò che si usa per?

E inoltre, non ottengo questa parte del libro:

Assegnare un valore Nonea una variabile è un modo per ripristinare il suo stato originale vuoto.

Cosa significa?

Le risposte sono state fantastiche, anche se non ho capito la maggior parte delle risposte a causa della mia scarsa conoscenza del mondo dei computer (non ho imparato lezioni, oggetti, ecc.). Cosa significa questa frase?

Assegnare un valore Nonea una variabile è un modo per ripristinare il suo stato originale vuoto.

Finale:

Finalmente ho avuto la mia risposta cercando altre risposte. Devo apprezzare tutte le persone che hanno dedicato il loro tempo per aiutarmi (in particolare Martijn Pieters e DSM), e vorrei poter scegliere tutte le risposte come le migliori, ma la selezione è limitata a una. Tutte le risposte sono state fantastiche.


39
Quel libro non è troppo utile; Nonenon è uno stato vuoto predefinito per le variabili.
Martijn Pieters

Al di sopra della mia testa, php è l'unica lingua il cui valore null è equivalente allo stato vuoto predefinito per una variabile. Ora mi chiedo quali altre lingue lo facciano.
Kojiro,

@kojiro perl, sebbene nessuno degli operatori di uguaglianza sia contento di confrontarsi con undef. probabilmente anche JavaScript, sebbene abbia entrambi nulle undefined.
Eevee,

Il valore predefinito della variabile javascript @kojiro è undefined, se lasciato non inizializzato.
thefourtheye,

Giusto, che è diverso da null, un punto che non riesco a fare a @MartijnPieters nella sua risposta.
Kojiro,

Risposte:


99

La risposta di Martijn spiega cosa Nonec'è in Python e afferma correttamente che il libro è fuorviante. Dal momento che i programmatori Python di regola non lo direbbero mai

Assegnare un valore Nonea una variabile è un modo per ripristinare il suo stato originale vuoto.

è difficile spiegare cosa significhi Briggs in un modo che abbia un senso e spieghi perché nessuno qui sembra soddisfatto. Un'analogia che può aiutare:

In Python, i nomi delle variabili sono come adesivi applicati sugli oggetti. Ogni adesivo ha un nome univoco scritto su di esso, e può essere su un solo oggetto alla volta, ma se lo desideri puoi mettere più di un adesivo sullo stesso oggetto. Quando scrivi

F = "fork"

metti l'adesivo "F" su un oggetto stringa "fork". Se poi scrivi

F = None

sposti l'adesivo Nonesull'oggetto.

Quello che Briggs ti sta chiedendo di immaginare è che non hai scritto l'adesivo "F", c'era già un Fadesivo sul None, e tutto ciò che hai fatto è stato spostarlo , da Nonea "fork". Quindi, quando digiti F = None, lo "ripristini [ting] al suo stato originale, vuoto", se decidessimo di considerare Nonecome significato empty state.

Posso vedere a cosa sta arrivando, ma è un brutto modo di vederlo. Se avvii Python e digiti print(F), vedi

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

e ciò NameErrorsignifica che Python non riconosce il nome F, perché non esiste tale adesivo . Se Briggs aveva ragione e si F = Noneripristina Fal suo stato originale, allora dovrebbe essere lì adesso, e dovremmo vedere

>>> print(F)
None

come facciamo dopo aver digitato F = Nonee applicato l'adesivo None.


Quindi è tutto ciò che sta succedendo. In realtà, Python viene fornito con alcuni adesivi già attaccati agli oggetti (nomi incorporati), ma altri devi scriverti con linee come F = "fork"e A = 2e c17 = 3.14, quindi puoi incollarli su altri oggetti in seguito (come F = 10o F = None; è tutto uguale .)

Briggs fa finta che tutti i possibili adesivi che potresti voler scrivere fossero già attaccati Noneall'oggetto.


1
scusa ma cosa intendi per Briggs? ti riferisci all'autore di questo libro? perché si chiama Jason R. Briggs.
The_Diver

@The_Diver: sì, è lui.
DSM,

Dove posso trovare maggiori informazioni sui nomi predefiniti di Python? Grazie.
The_Diver

3
Questa è un'ottima spiegazione per un non programmatore. Grazie mille!
Christina,

67

Noneè solo un valore comunemente usato per indicare "vuoto" o "nessun valore qui". È un oggetto segnale ; ha significato solo perché la documentazione di Python afferma che ha quel significato.

Esiste una sola copia di quell'oggetto in una determinata sessione dell'interprete Python.

Se si scrive una funzione e tale funzione non utilizza un'istruzione esplicita return, Noneviene restituita, ad esempio. In questo modo, la programmazione con funzioni è molto semplificata; una funzione restituisce sempre qualcosa , anche se è solo quell'unico Noneoggetto.

Puoi testarlo esplicitamente:

if foo is None:
    # foo is set to None

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

Un altro uso è quello di fornire parametri opzionali per le funzioni di default 'vuoto':

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

La funzione spam()ha un argomento facoltativo; se si chiama spam()senza specificarlo, Noneviene assegnato il valore predefinito , facilitando il rilevamento se la funzione è stata chiamata con un argomento o meno.

Altre lingue hanno concetti simili. SQL ha NULL; JavaScript ha undefined e null , ecc.

Nota che in Python esistono variabili in virtù dell'utilizzo. Non è necessario dichiarare prima una variabile, quindi non ci sono variabili veramente vuote in Python. L'impostazione di una variabile su non Noneè quindi la stessa cosa dell'impostazione su un valore vuoto predefinito; Noneè anche un valore, sebbene sia spesso usato per segnalare vuoti. Il libro che stai leggendo su questo punto è fuorviante.


1
Credo che la semantica di vuoto sono diversi da quelli di undefinedness . Quindi non sono sicuro che le controparti JavaScript e SQL stiano chiarendo: potrebbero confondere il problema. JavaScript ha entrambi undefined e null .
Kojiro,

@kojiro: undefinedè un oggetto in JavaScript e puoi usarlo esplicitamente proprio come puoi usare Nonein Python. È un oggetto segnale, con lo stesso significato.
Martijn Pieters

@kojiro: SQL non è un linguaggio di programmazione, ma NULLè ancora qualcosa che può essere assegnato e testato esplicitamente.
Martijn Pieters

5
@MartijnPieters: SQL è un linguaggio di programmazione, solo uno scopo molto specifico, dichiarativo.
danielkza,

3
@daniel: se SQL si qualifica come linguaggio di programmazione è stato un lungo dibattito ... Vedi stackoverflow.com/questions/900055/… per angoli interessanti.
Martijn Pieters

23

Questo è ciò che la documentazione di Python ha da dire su None:

L'unico valore di types.NoneType. Nessuno viene spesso utilizzato per rappresentare l'assenza di un valore, come quando gli argomenti predefiniti non vengono passati a una funzione.

Modificato nella versione 2.4: le assegnazioni a None sono illegali e generano un SyntaxError.

Nota I nomi Nessuno e debug non possono essere riassegnati (le assegnazioni, anche come nome di attributo, aumentano SyntaxError), quindi possono essere considerate costanti "vere".

  1. Confermiamo il tipo di Noneprima

    print type(None)
    print None.__class__

    Produzione

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

Fondamentalmente, NoneTypeè un tipo di dati proprio come int, floatecc. Puoi controllare l'elenco dei tipi predefiniti disponibili in Python in 8.15. tipi: nomi per tipi incorporati .

  1. E, Noneè un'istanza di NoneTypeclasse. Quindi potremmo voler creare istanze di Nonenoi stessi. Proviamo quello

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

    Produzione

    0
    TypeError: cannot create 'NoneType' instances

Quindi, chiaramente, non è possibile creare NoneTypeistanze. Non dobbiamo preoccuparci dell'unicità del valore None.

  1. Controlliamo come abbiamo implementato Noneinternamente.

    print dir(None)

    Produzione

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

Tranne __setattr__, tutti gli altri sono attributi di sola lettura. Pertanto, non è possibile modificare gli attributi di None.

  1. Proviamo ad aggiungere nuovi attributi a None

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

    Produzione

    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'

Le istruzioni sopra riportate producono questi messaggi di errore, rispettivamente. Ciò significa che non possiamo creare attributi dinamicamente su Noneun'istanza.

  1. Controlliamo cosa succede quando assegniamo qualcosa None. Come da documentazione, dovrebbe essere lanciato a SyntaxError. Significa che, se assegniamo qualcosa a None, il programma non verrà eseguito affatto.

    None = 1

    Produzione

    SyntaxError: cannot assign to None

Lo abbiamo stabilito

  1. None è un'istanza di NoneType
  2. None non può avere nuovi attributi
  3. Gli attributi esistenti di Nonenon possono essere modificati.
  4. Non possiamo creare altre istanze di NoneType
  5. Non possiamo nemmeno cambiare il riferimento Noneassegnandogli dei valori.

Quindi, come menzionato nella documentazione, Nonepuò davvero essere considerato come un true constant.

Buona conoscenza None:)


Molto molto interessante !! un dubbio di cosa serve __setattr__nessuno
Grijesh Chauhan,

9

Il libro a cui ti riferisci sta chiaramente cercando di semplificare notevolmente il significato di None. Le variabili Python non hanno uno stato iniziale vuoto: le variabili Python sono associate (solo) quando sono definite . Non puoi creare una variabile Python senza dargli un valore.

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

ma a volte vuoi che una funzione significhi cose diverse a seconda che una variabile sia definita o meno. È possibile creare un argomento con un valore predefinito di None:

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

Il fatto che questo valore sia il Nonevalore speciale non è estremamente importante in questo caso. Avrei potuto usare qualsiasi valore predefinito:

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

... ma avere in Nonegiro ci dà due vantaggi:

  1. Non dobbiamo scegliere un valore speciale come il -1cui significato non è chiaro, e
  2. Potrebbe essere necessario che la nostra funzione sia gestita -1come un normale input.
>>> test(-1)
no x here

oops!

Quindi il libro è un po 'fuorviante soprattutto nell'uso della parola reset - l'assegnazione Nonea un nome è un segnale per un programmatore che quel valore non viene utilizzato o che la funzione dovrebbe comportarsi in qualche modo predefinito, ma per ripristinare un valore allo stato originale non definito è necessario utilizzare la delparola chiave:

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

Altre risposte hanno già spiegato il significato di None magnificamente. Tuttavia, vorrei ancora gettare più luce su questo usando un esempio.

Esempio:

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

Ora prova a indovinare l'output dell'elenco sopra. Bene, la risposta è sorprendentemente come di seguito:

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

Ma perché?

Molti si aspetteranno erroneamente che list1 sia uguale a [10] e list3 uguale a ['a'] , pensando che l'argomento list verrà impostato sul suo valore predefinito di [] ogni volta che viene chiamato extList.

Tuttavia, ciò che effettivamente accade è che il nuovo elenco predefinito viene creato una sola volta quando viene definita la funzione e che lo stesso elenco viene quindi utilizzato successivamente ogni volta che viene invocato extList senza specificare un argomento dell'elenco. Questo perché le espressioni negli argomenti predefiniti vengono calcolate quando viene definita la funzione, non quando viene chiamata .

list1 e list3 funzionano quindi sullo stesso elenco predefinito, mentre list2 opera su un elenco separato che ha creato (passando il proprio elenco vuoto come valore per il parametro list).


'Nessuno' il salvatore: (modifica l'esempio sopra per produrre il comportamento desiderato)

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 questa implementazione rivista, l'output sarebbe:

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

Nota - Esempio di credito a toptal.com


3

None è un oggetto singleton (nel senso che esiste un solo None), usato in molti punti del linguaggio e della libreria per rappresentare l'assenza di qualche altro valore.


Ad esempio:
se dè un dizionario, d.get(k)restituirà d[k]se esiste, ma Nonese dnon ha una chiave k.

Leggi queste informazioni da un fantastico blog: http://python-history.blogspot.in/


3

Tutte queste sono buone risposte ma penso che ci sia altro per spiegare il perché None sia utile.

Immagina di collezionare RSVP per un matrimonio. Vuoi registrare se ogni persona parteciperà. Se stanno partecipando, sei pronto person.attending = True. Se non vi partecipano, impostate person.attending = False. Se non hai ricevuto alcun RSVP, allora person.attending = None. In questo modo puoi distinguere tra nessuna informazione None- e una risposta negativa.


1

Adoro gli esempi di codice (oltre alla frutta), quindi lascia che ti mostri

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

Nessuno non significa nulla, non ha valore.

Nessuno viene valutato come Falso.


8
print(None)stampe .. None. Lo fa non , come lei suggerisce, stampa nulla.
Martijn Pieters

il REPL non mostra nulla per Nonese è il risultato dell'ultima espressione. (che è utile soprattutto per le funzioni che non intendono restituire un valore.)
Eevee

Eppure, errore mio, stavo usando IDLE e ho assunto che stampasse variabili, apparentemente usa un sostituto. Attualmente sto usando SO per perfezionare le mie abilità di lettura e comprensione di python / javascript / codice, quindi sto facendo alcuni errori :(
Azeirah

2
IDLE, come il prompt dell'interprete interattivo Python, nasconde esplicitamente Nonese questo è il risultato di un'espressione, principalmente per non ingombrare l'output.
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 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.