Was ist ein None-Wert?

130

Ich habe Python studiert und ein Kapitel gelesen, das den NoneWert beschreibt , aber leider ist dieses Buch an einigen Stellen nicht sehr klar. Ich dachte, ich würde die Antwort auf meine Frage finden, wenn ich sie dort teile.

Ich möchte wissen, was der NoneWert ist und wofür Sie ihn verwenden.

Und außerdem verstehe ich diesen Teil des Buches nicht:

Das Zuweisen eines Werts von Nonezu einer Variablen ist eine Möglichkeit, sie auf ihren ursprünglichen, leeren Zustand zurückzusetzen.

Was bedeutet das?

Die Antworten waren großartig, obwohl ich die meisten Antworten aufgrund meiner geringen Kenntnisse der Computerwelt nicht verstand (ich habe nichts über Klassen, Objekte usw. gelernt). Was bedeutet dieser Satz?

Das Zuweisen eines Werts von Nonezu einer Variablen ist eine Möglichkeit, sie auf ihren ursprünglichen, leeren Zustand zurückzusetzen.

Finale:

Schließlich habe ich meine Antwort erhalten, indem ich nach verschiedenen Antworten gesucht habe. Ich muss all die Menschen schätzen, die sich die Zeit genommen haben, mir zu helfen (insbesondere Martijn Pieters und DSM), und ich wünschte, ich könnte alle Antworten als die besten auswählen, aber die Auswahl ist auf eine beschränkt. Alle Antworten waren großartig.

The_Diver
quelle
39
Das Buch ist nicht allzu hilfreich; Noneist kein leerer Standardzustand für Variablen.
Martijn Pieters
Auf den ersten Blick ist PHP die einzige Sprache, deren Nullwert dem Standardleerstatus für eine Variable entspricht. Jetzt frage ich mich, welche anderen Sprachen das tun.
Kojiro
@kojiro perl, obwohl keiner der Gleichstellungsoperatoren sich über einen Vergleich mit freut undef. auch wohl Javascript, obwohl es sowohl nullund hat undefined.
Eevee
Der Standardwert der @ kojiro-Javascript-Variablen ist undefined, wenn sie nicht initialisiert wird.
thefourtheye
Richtig, was sich von einem Punkt unterscheidetnull , den ich @MartijnPieters in seiner Antwort nicht vorstelle.
Kojiro

Antworten:

99

Martijns Antwort erklärt, was Nonein Python enthalten ist, und gibt zu Recht an, dass das Buch irreführend ist. Da würden Python-Programmierer in der Regel nie sagen

Das Zuweisen eines Werts von Nonezu einer Variablen ist eine Möglichkeit, sie auf ihren ursprünglichen, leeren Zustand zurückzusetzen.

Es ist schwer zu erklären, was Briggs auf sinnvolle Weise bedeutet und warum hier niemand damit zufrieden zu sein scheint. Eine Analogie, die helfen kann:

In Python sind Variablennamen wie Aufkleber auf Objekten. Auf jedem Aufkleber ist ein eindeutiger Name geschrieben, und es kann immer nur ein Objekt gleichzeitig sein. Sie können jedoch auch mehr als einen Aufkleber auf dasselbe Objekt kleben, wenn Sie möchten. Wenn du schreibst

F = "fork"

Sie kleben den Aufkleber "F" auf ein Zeichenfolgenobjekt "fork". Wenn du dann schreibst

F = None

Sie verschieben den Aufkleber auf das NoneObjekt.

Briggs bittet Sie, sich vorzustellen, dass Sie den Aufkleber nicht geschrieben haben"F" , dass bereits ein FAufkleber auf dem Aufkleber Nonewar und Sie ihn nur von nach verschoben haben . Wenn Sie also tippen , "setzen Sie es auf seinen ursprünglichen, leeren Zustand zurück", wenn wir uns entschieden haben, es als Bedeutung zu behandeln .None"fork"F = NoneNoneempty state

Ich kann sehen, worauf er hinaus will, aber das ist eine schlechte Sichtweise. Wenn Sie Python starten und eingeben print(F), sehen Sie

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

und das NameErrorbedeutet, dass Python den Namen nicht erkennt F, weil es keinen solchen Aufkleber gibt . Wenn Briggs Recht und waren F = Nonezurückgesetzt Fin seinen ursprünglichen Zustand, dann sollte es nun sein, und wir sollten sehen ,

>>> print(F)
None

wie wir es tun, nachdem wir F = Noneden Aufkleber getippt und aufgeklebt haben None.


Das ist alles was los ist. In Wirklichkeit enthält Python einige Aufkleber, die bereits an Objekten angebracht sind (integrierte Namen), andere müssen Sie selbst mit Zeilen wie F = "fork"und A = 2und schreiben c17 = 3.14, und Sie können sie später auf andere Objekte kleben (wie F = 10oder F = None; es ist alles das Gleiche .)

Briggs gibt vor, dass alle möglichen Aufkleber, die Sie schreiben möchten, bereits auf dem NoneObjekt kleben.

DSM
quelle
1
Entschuldigung, aber was meinst du mit Briggs? Beziehst du dich auf den Autor dieses Buches? Weil er Jason R. Briggs heißt.
The_Diver
@ The_Diver: Ja, das ist er.
DSM
Wo finde ich weitere Informationen zu den in Python integrierten Namen? Danke.
The_Diver
3
Dies ist eine großartige Erklärung für einen Nicht-Programmierer. Vielen Dank!
Christina
67

Noneist nur ein Wert, der üblicherweise verwendet wird, um "leer" oder "hier kein Wert" zu bezeichnen. Es ist ein Signalobjekt ; Es hat nur eine Bedeutung, weil die Python-Dokumentation besagt, dass es diese Bedeutung hat.

In einer bestimmten Python-Interpretersitzung gibt es nur eine Kopie dieses Objekts.

Wenn Sie eine Funktion schreiben und diese Funktion keine explizite returnAnweisung verwendet, Nonewird sie beispielsweise stattdessen zurückgegeben. Auf diese Weise wird die Programmierung mit Funktionen erheblich vereinfacht. eine Funktion immer wieder etwas , auch wenn es nur , dass man NoneObjekt.

Sie können es explizit testen:

if foo is None:
    # foo is set to None

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

Eine andere Verwendung besteht darin, optionalen Parametern Funktionen einen 'leeren' Standard zuzuweisen:

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

Die Funktion spam()hat ein optionales Argument. Wenn Sie spam()ohne Angabe aufrufen , wird der Standardwert Noneangegeben, sodass Sie leicht erkennen können, ob die Funktion mit einem Argument aufgerufen wurde oder nicht.

Andere Sprachen haben ähnliche Konzepte. SQL hat NULL; JavaScript hat undefined und null usw.

Beachten Sie, dass in Python Variablen aufgrund ihrer Verwendung vorhanden sind. Sie müssen nicht zuerst eine Variable deklarieren, daher gibt es in Python keine wirklich leeren Variablen. Das Setzen einer Variablen auf Noneist dann nicht dasselbe wie das Setzen auf einen leeren Standardwert. Noneist auch ein Wert, obwohl er oft verwendet wird, um Leere zu signalisieren . Das Buch, das Sie lesen, ist in diesem Punkt irreführend.

Martijn Pieters
quelle
1
Ich denke, die Semantik der Leere unterscheidet sich von der der Undefiniertheit . Ich bin mir also nicht sicher, ob die Gegenstücke zu JavaScript und SQL klarstellen - sie können das Problem verwirren. JavaScript hat sowohl undefined und null .
Kojiro
@kojiro: undefinedist ein Objekt in JavaScript, und Sie können dieses Objekt explizit verwenden, genau wie Sie es Nonein Python verwenden können. Es ist ein Signalobjekt mit fast der gleichen Bedeutung.
Martijn Pieters
@kojiro: SQL ist keine Programmiersprache, kann aber NULLdennoch explizit zugewiesen und getestet werden.
Martijn Pieters
5
@MartijnPieters: SQL ist eine Programmiersprache, nur ein sehr spezifischer, deklarativer Zweck.
Danielkza
3
@daniel: Ob SQL als Programmiersprache qualifiziert ist, war eine lange Debatte ... Interessante Aspekte finden Sie unter stackoverflow.com/questions/900055/… .
Martijn Pieters
23

Dies ist, was die Python-Dokumentation zu sagen hat None:

Der einzige Wert von types.NoneType. Keine wird häufig verwendet, um das Fehlen eines Werts darzustellen, beispielsweise wenn Standardargumente nicht an eine Funktion übergeben werden.

In Version 2.4 geändert: Zuweisungen zu Keine sind unzulässig und lösen einen SyntaxError aus.

Hinweis Die Namen None und Debug können nicht neu zugewiesen werden (Zuweisungen zu ihnen, auch als Attributname, lösen SyntaxError aus), sodass sie als "wahre" Konstanten betrachtet werden können.

  1. Lassen Sie uns bestätigen die Art der Noneersten

    print type(None)
    print None.__class__

    Ausgabe

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

Grundsätzlich NoneTypeist ein Datentyp wie int, floatetc. Check - out kann die Liste der Standardtypen in Python in 8,15. Typen - Namen für integrierte Typen .

  1. Und Noneist eine Instanz der NoneTypeKlasse. Vielleicht möchten wir also Instanzen von Noneuns selbst erstellen . Lass es uns versuchen

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

    Ausgabe

    0
    TypeError: cannot create 'NoneType' instances

So klar, kann keine NoneTypeInstanzen erstellen . Wir müssen uns keine Sorgen um die Einzigartigkeit des Wertes machen None.

  1. Lassen Sie uns überprüfen, wie wir Noneintern implementiert haben .

    print dir(None)

    Ausgabe

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

Außer __setattr__, alle anderen Schreibschutz -Attribute. Es gibt also keine Möglichkeit, die Attribute von zu ändern None.

  1. Versuchen wir, neue Attribute hinzuzufügen None

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

    Ausgabe

    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'

Die oben gezeigten Anweisungen erzeugen jeweils diese Fehlermeldungen. Dies bedeutet, dass wir keine Attribute dynamisch für eine NoneInstanz erstellen können .

  1. Lassen Sie uns überprüfen, was passiert, wenn wir etwas zuweisen None. Gemäß der Dokumentation sollte es ein werfen SyntaxError. Das heißt, wenn wir etwas zuweisen, Nonewird das Programm überhaupt nicht ausgeführt.

    None = 1

    Ausgabe

    SyntaxError: cannot assign to None

Das haben wir festgestellt

  1. None ist eine Instanz von NoneType
  2. None kann keine neuen Attribute haben
  3. Bestehende Attribute von Nonekönnen nicht geändert werden.
  4. Wir können keine anderen Instanzen von erstellen NoneType
  5. Wir können den Verweis nicht einmal ändern, Noneindem wir ihm Werte zuweisen.

Also, wie in der Dokumentation erwähnt, Nonekann wirklich als betrachtet werden true constant.

Glückliches Wissen None:)

thefourtheye
quelle
Sehr sehr interessant !! ein Zweifel, was __setattr__für keine verwendet wird
Grijesh Chauhan
9

Das Buch, auf das Sie sich beziehen, versucht eindeutig, die Bedeutung von stark zu vereinfachen None. Python - Variablen nicht haben eine anfängliche, leeren Zustand - Python Variablen gebunden (nur) , wenn sie definiert sind . Sie können eine Python-Variable nicht erstellen, ohne einen Wert anzugeben.

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

Manchmal möchten Sie jedoch festlegen, dass eine Funktion unterschiedliche Bedeutungen hat, je nachdem, ob eine Variable definiert ist oder nicht. Sie können ein Argument mit dem Standardwert erstellen None:

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

Die Tatsache, dass dieser Wert der Sonderwert Noneist, ist in diesem Fall nicht besonders wichtig. Ich hätte jeden Standardwert verwenden können:

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

… Aber Noneherum zu haben bringt uns zwei Vorteile:

  1. Wir müssen keinen speziellen Wert auswählen, -1dessen Bedeutung unklar ist, und
  2. Unsere Funktion muss möglicherweise tatsächlich -1als normale Eingabe behandelt werden.
>>> test(-1)
no x here

Hoppla!

Daher ist das Buch ein wenig irreführend, vor allem in Bezug auf die Verwendung des Wortes " Zurücksetzen". Das Zuweisen Noneeines Namens ist ein Signal an einen Programmierer, dass dieser Wert nicht verwendet wird oder dass sich die Funktion standardmäßig verhalten sollte, sondern um einen Wert zurückzusetzen In den ursprünglichen, undefinierten Zustand müssen Sie das delSchlüsselwort verwenden:

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

Andere Antworten haben die Bedeutung von None bereits wunderschön erklärt. Ich möchte dies jedoch noch anhand eines Beispiels näher erläutern.

Beispiel:

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

Versuchen Sie nun, die Ausgabe der obigen Liste zu erraten. Nun, die Antwort ist überraschend wie folgt:

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

Aber wieso?

Viele werden fälschlicherweise erwarten, dass list1 gleich [10] und list3 gleich ['a'] ist , da sie denken, dass das list-Argument bei jedem Aufruf von extensList auf den Standardwert [] gesetzt wird.

Was jedoch tatsächlich passiert, ist, dass die neue Standardliste nur einmal erstellt wird, wenn die Funktion definiert wird , und dass dieselbe Liste anschließend verwendet wird, wenn expandList aufgerufen wird, ohne dass ein Listenargument angegeben wird. Das ist weil Ausdrücke in Standardargumenten berechnet werden, wenn die Funktion definiert wird, nicht wenn sie aufgerufen wird .

list1 und list3 arbeiten daher mit derselben Standardliste, während list2 mit einer separaten Liste arbeitet, die sie erstellt hat (indem sie ihre eigene leere Liste als Wert für den Listenparameter übergibt).


'Keiner' der Retter: (Ändern Sie das obige Beispiel, um das gewünschte Verhalten zu erzielen.)

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

Mit dieser überarbeiteten Implementierung wäre die Ausgabe:

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

Hinweis - Beispielgutschrift für toptal.com

Jadav Bheda
quelle
3

None ist ein Singleton-Objekt (dh es gibt nur ein None), das an vielen Stellen in der Sprache und Bibliothek verwendet wird, um das Fehlen eines anderen Werts darzustellen.


Zum Beispiel:
Wenn dein Wörterbuch ist, d.get(k)wird zurückkehren , d[k]wenn es vorhanden ist , aber Nonewenn dkeine Schlüssel hat k.

Lesen Sie diese Informationen aus einem großartigen Blog: http://python-history.blogspot.in/

GrvTyagi
quelle
3

All dies sind gute Antworten, aber ich denke, es gibt mehr zu erklären, warum None nützlich ist.

Stellen Sie sich vor, Sie sammeln RSVPs für eine Hochzeit. Sie möchten aufzeichnen, ob jede Person teilnehmen wird. Wenn sie anwesend sind, legen Sie fest person.attending = True. Wenn sie nicht anwesend sind, setzen Sie person.attending = False. Wenn Sie kein RSVP erhalten haben, dann person.attending = None. Auf diese Weise können Sie zwischen keiner Information - None- und einer negativen Antwort unterscheiden.

Dab Brill
quelle
1

Ich liebe Codebeispiele (sowie Obst), also lass es mich dir zeigen

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

Keiner bedeutet nichts, es hat keinen Wert.

Keiner wird mit Falsch bewertet.

Azeirah
quelle
8
print(None)druckt .. None. Es tut nicht , wie Sie vorschlagen, drucken nichts.
Martijn Pieters
Die REPL zeigt nur dann nichts an, Nonewenn es das Ergebnis des letzten Ausdrucks ist. (Dies ist vor allem für Funktionen hilfreich, die keinen Wert zurückgeben sollen.)
Eevee
Eugh, mein Fehler, ich habe IDLE verwendet und angenommen, dass es gedruckte Variablen sind, anscheinend wird repl verwendet. Ich benutze derzeit SO, um meine eigenen Fähigkeiten zum Lesen und Verstehen von Python / Javascript / Code zu perfektionieren, also mache ich einige Fehler :(
Azeirah
2
IDLE verbirgt wie die interaktive Python-Interpreter-Eingabeaufforderung explizit, Nonewenn dies das Ergebnis eines Ausdrucks ist, hauptsächlich, um die Ausgabe nicht zu überladen.
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
quelle