Null-Objekt in Python

Lesezeit: 15 Minuten

Benutzeravatar von Lizard
Eidechse

Wie beziehe ich mich auf die Nullobjekt in Python?

Benutzeravatar von Ben James
Ben James

In Python ist das „Null“-Objekt das Singleton None.

Um zu überprüfen, ob etwas ist Noneverwenden Sie die is Identitätsoperator:

if foo is None:
    ...

  • Und der Grund für die Wahl egg is None Über egg == None: Letzteres kann überladen werden und bricht wahrscheinlich zusammen, wenn ein gültiges Objekt mit None verglichen wird (hängt davon ab, wie es implementiert ist, aber Sie erwarten nicht, dass jeder Vergleiche mit None berücksichtigt, oder?), while is funktioniert immer gleich.

    Benutzer395760

    20. Juli 2010 um 12:25 Uhr

  • Warum haben die Python-Designer nicht einfach “null” gewählt? Man muss einfach anders sein, nicht wahr? 😉

    – Vidar

    26. März 2013 um 9:44 Uhr

  • @Vidar ‘None’ ist kein Fehlen eines Objekts (wie ‘null’ eine Nullreferenz ist), es ist ein tatsächliches Objekt. Sie erhalten niemals ein ‘None’-Objekt, das für ein Objekt übergeben wird, das einen anderen Typ als ‘NoneType’ hat. Es ist auch kein Sprachkonzept. Es ist nicht in die Sprache Python integriert, sondern Teil der Standardbibliothek von Python. Keine !== (ähm) Null

    – Rushyo

    12. Juni 2013 um 12:17 Uhr

  • @ naught101 Es würde keinen Zweck erfüllen; da es kein Konzept von Zeigern gibt. Wenn Sie die ctypes-Bibliothek verwenden, wird None als Synonym für die Adresse Null verwendet, aber es gibt immer noch kein Sprachkonzept einer ‘Nullreferenz’. In Python haben Sie immer auf eine Art Objekt verwiesen, selbst wenn dieses Objekt None ist. Ich vermute, dass dies die Sprache stark vereinfacht.

    – Rushyo

    2. September 2014 um 13:26 Uhr


  • großartige Präsentation, die den “Milliarden-Dollar-Fehler” erklärt, der der Null-Ref ist: infoq.com/presentations/…. Andere Optionen anstelle von null sind Optionen oder vielleicht (benutzerdefinierte) Typen.

    – Michael Trouv

    8. April 2015 um 23:56 Uhr


Benutzeravatar von Michael Ekoka
Michael Ekoka

NonePython ist null?

Da ist kein null in Python; stattdessen gibt es None. Wie bereits erwähnt, der genaueste Weg, um zu testen, ob etwas gegeben wurde None als Wert ist die zu verwenden is Identitätsoperator, der testet, ob zwei Variablen auf dasselbe Objekt verweisen.

>>> foo is None
True
>>> foo = 'bar'
>>> foo is None
False

Die Grundlagen

Es gibt und kann nur einen geben None

None ist die einzige Instanz der Klasse NoneType und alle weiteren Versuche, diese Klasse zu instanziieren, werden dasselbe Objekt zurückgeben, was macht None ein Einzelgänger. Neulinge in Python sehen oft Fehlermeldungen, die erwähnen NoneType und frage mich, was es ist. Es ist meine persönliche Meinung, dass man diese Meldungen einfach nur erwähnen könnte None namentlich, weil, wie wir gleich sehen werden, None lässt wenig Raum für Mehrdeutigkeiten. Also, wenn Sie einige sehen TypeError Nachricht, die das erwähnt NoneType kann dies nicht oder kann das nicht, wisse einfach, dass es einfach das eine ist None das wurde auf eine Weise verwendet, die es nicht kann.

Ebenfalls, None ist eine eingebaute Konstante. Sobald Sie Python starten, steht es überall zur Verfügung, ob in Modul, Klasse oder Funktion. NoneType im Gegensatz dazu nicht, Sie müssten zuerst durch Abfragen einen Verweis darauf erhalten None für seine Klasse.

>>> NoneType
NameError: name 'NoneType' is not defined
>>> type(None)
NoneType

Du kannst nachschauen Nonemit der Identitätsfunktion von Python id(). Es gibt die eindeutige Nummer zurück, die einem Objekt zugewiesen ist, jedes Objekt hat eine. Wenn die ID zweier Variablen gleich ist, dann zeigen sie tatsächlich auf dasselbe Objekt.

>>> NoneType = type(None)
>>> id(None)
10748000
>>> my_none = NoneType()
>>> id(my_none)
10748000
>>> another_none = NoneType()
>>> id(another_none)
10748000
>>> def function_that_does_nothing(): pass
>>> return_value = function_that_does_nothing()
>>> id(return_value)
10748000

None kann nicht überschrieben werden

In viel älteren Python-Versionen (vor 2.4) war eine Neuzuweisung möglich None, aber nicht mehr. Nicht einmal als Klassenattribut oder innerhalb einer Funktion.

# In Python 2.7
>>> class SomeClass(object):
...     def my_fnc(self):
...             self.None="foo"
SyntaxError: cannot assign to None
>>> def my_fnc():
        None="foo"
SyntaxError: cannot assign to None

# In Python 3.5
>>> class SomeClass:
...     def my_fnc(self):
...             self.None="foo"
SyntaxError: invalid syntax
>>> def my_fnc():
        None="foo"
SyntaxError: cannot assign to keyword

Es ist daher davon auszugehen, dass alle None Referenzen sind die gleichen. Es gibt keinen “Brauch” None.

Zum Testen None benutze die is Operator

Beim Schreiben von Code könnten Sie versucht sein, dies zu testen Nichtigkeit so was:

if value==None:
    pass

Oder um so auf Unwahrheit zu testen

if not value:
    pass

Sie müssen die Auswirkungen verstehen und wissen, warum es oft eine gute Idee ist, explizit zu sein.

Fall 1: Testen, ob ein Wert vorhanden ist None

Warum machen

value is None

statt

value==None

?

Das erste ist äquivalent zu:

id(value)==id(None)

Während der Ausdruck value==None wird tatsächlich so angewendet

value.__eq__(None)

Wenn der Wert wirklich ist None dann bekommst du was du erwartet hast.

>>> nothing = function_that_does_nothing()
>>> nothing.__eq__(None)
True

In den meisten Fällen wird das Ergebnis das gleiche sein, aber die __eq__() -Methode öffnet eine Tür, die jegliche Genauigkeitsgarantie aufhebt, da sie in einer Klasse überschrieben werden kann, um ein spezielles Verhalten bereitzustellen.

Betrachten Sie diese Klasse.

>>> class Empty(object):
...     def __eq__(self, other):
...         return not other

Also probierst du es aus None und es funktioniert

>>> empty = Empty()
>>> empty==None
True

Aber dann funktioniert es auch auf dem leeren String

>>> empty==''
True

Und doch

>>> ''==None
False
>>> empty is None
False

Fall 2: Verwenden None als Boolean

Die folgenden zwei Tests

if value:
    # Do something

if not value:
    # Do something

werden tatsächlich als bewertet

if bool(value):
    # Do something

if not bool(value):
    # Do something

None ist ein “Falsey”, was bedeutet, dass es zurückgegeben wird, wenn es in einen booleschen Wert umgewandelt wird False und falls angewendet die not Betreiber wird es zurückkehren True. Beachten Sie jedoch, dass es sich nicht um eine einzigartige Eigenschaft handelt None. Zusätzlich zu False selbst wird die Eigenschaft von leeren Listen, Tupeln, Mengen, Wörtern, Zeichenfolgen sowie 0 und allen Objekten von Klassen geteilt, die die implementieren __bool__() magische Methode zur Rückkehr False.

>>> bool(None)
False
>>> not None
True

>>> bool([])
False
>>> not []
True

>>> class MyFalsey(object):
...     def __bool__(self):
...         return False
>>> f = MyFalsey()
>>> bool(f)
False
>>> not f
True

Wenn Sie also auf folgende Weise auf Variablen testen, achten Sie besonders darauf, was Sie in den Test einbeziehen oder daraus ausschließen:

def some_function(value=None):
    if not value:
        value = init_value()

Wollten Sie oben anrufen init_value() wenn der Wert speziell auf eingestellt ist Noneoder meintest du das auf einen Wert gesetzt 0, oder der leere String, oder eine leere Liste soll auch die Initialisierung auslösen? Wie gesagt, sei achtsam. Wie so oft in Python explizit ist besser als implizit.

None in der Praxis

None als Signalwert verwendet

None hat in Python einen Sonderstatus. Dies ist ein beliebter Basiswert, da viele Algorithmen ihn als außergewöhnlichen Wert behandeln. In solchen Szenarien kann es als Flag verwendet werden, um zu signalisieren, dass eine Bedingung eine spezielle Behandlung erfordert (z. B. das Setzen eines Standardwerts).

Sie können zuweisen None zu den Schlüsselwortargumenten einer Funktion und dann explizit darauf testen.

def my_function(value, param=None):
    if param is None:
        # Do something outrageous!

Sie können es als Standard zurückgeben, wenn Sie versuchen, zum Attribut eines Objekts zu gelangen, und es dann explizit testen, bevor Sie etwas Besonderes tun.

value = getattr(some_obj, 'some_attribute', None)
if value is None:
    # do something spectacular!

Standardmäßig ein Wörterbuch get() Methode zurück None beim Versuch, auf einen nicht vorhandenen Schlüssel zuzugreifen:

>>> some_dict = {}
>>> value = some_dict.get('foo')
>>> value is None
True

Wenn Sie versuchen würden, darauf zuzugreifen, indem Sie die tiefgestellte Schreibweise a verwenden KeyError erhoben würden

>>> value = some_dict['foo']
KeyError: 'foo'

Ebenso, wenn Sie versuchen, ein nicht vorhandenes Element zu platzieren

>>> value = some_dict.pop('foo')
KeyError: 'foo'

die Sie mit einem normalerweise eingestellten Standardwert unterdrücken können None

value = some_dict.pop('foo', None)
if value is None:
    # Booom!

None wird sowohl als Flag als auch als gültiger Wert verwendet

Die oben beschriebenen Verwendungen von None gelten, wenn es nicht als gültiger Wert angesehen wird, sondern eher als Signal, etwas Besonderes zu tun. Es gibt jedoch Situationen, in denen es manchmal wichtig ist zu wissen, wo None stammt, weil es, obwohl es als Signal verwendet wird, auch Teil der Daten sein könnte.

Wenn Sie ein Objekt nach seinem Attribut mit abfragen getattr(some_obj, 'attribute_name', None) zurückkommen None sagt Ihnen nicht, ob das Attribut, auf das Sie zugreifen wollten, festgelegt wurde None oder wenn es überhaupt vom Objekt fehlte. Die gleiche Situation beim Zugriff auf einen Schlüssel aus einem Wörterbuch, z some_dict.get('some_key')du weißt nicht ob some_dict['some_key'] fehlt oder nur darauf eingestellt ist None. Wenn Sie diese Informationen benötigen, besteht die übliche Vorgehensweise darin, direkt zu versuchen, auf das Attribut oder den Schlüssel innerhalb von a zuzugreifen try/except konstruieren:

try:
    # Equivalent to getattr() without specifying a default
    # value = getattr(some_obj, 'some_attribute')
    value = some_obj.some_attribute
    # Now you handle `None` the data here
    if value is None:
        # Do something here because the attribute was set to None
except AttributeError:
    # We're now handling the exceptional situation from here.
    # We could assign None as a default value if required.
    value = None
    # In addition, since we now know that some_obj doesn't have the
    # attribute 'some_attribute' we could do something about that.
    log_something(some_obj)

Ähnlich mit dict:

try:
    value = some_dict['some_key']
    if value is None:
        # Do something here because 'some_key' is set to None
except KeyError:
    # Set a default
    value = None
    # And do something because 'some_key' was missing
    # from the dict.
    log_something(some_dict)

Die beiden obigen Beispiele zeigen, wie Objekt- und Wörterbuchfälle behandelt werden. Was ist mit Funktionen? Das Gleiche, aber wir verwenden zu diesem Zweck das Schlüsselwortargument doppelte Sternchen:

def my_function(**kwargs):
    try:
        value = kwargs['some_key']
        if value is None:
            # Do something because 'some_key' is explicitly
            # set to None
    except KeyError:
        # We assign the default
        value = None
        # And since it's not coming from the caller.
        log_something('did not receive "some_key"')

None nur als gültiger Wert verwendet

Wenn Sie feststellen, dass Ihr Code mit dem oben Gesagten übersät ist try/except Muster einfach zu unterscheiden None Fahnen u None Daten, dann verwenden Sie einfach einen anderen Testwert. Es gibt ein Muster, bei dem ein Wert, der außerhalb des Satzes gültiger Werte liegt, als Teil der Daten in eine Datenstruktur eingefügt und zum Steuern und Testen spezieller Bedingungen (z. B. Grenzen, Status usw.) verwendet wird. Einen solchen Wert nennt man a Wächter und es kann so verwendet werden None wird als Signal verwendet. Es ist trivial, einen Sentinel in Python zu erstellen.

undefined = object()

Das undefined Das obige Objekt ist einzigartig und macht nicht viel von allem, was für ein Programm von Interesse sein könnte, es ist daher ein ausgezeichneter Ersatz für None als Fahne. Es gelten einige Einschränkungen, mehr dazu nach dem Code.

Mit Funktion

def my_function(value, param1=undefined, param2=undefined):
    if param1 is undefined:
        # We know nothing was passed to it, not even None
        log_something('param1 was missing')
        param1 = None


    if param2 is undefined:
        # We got nothing here either
        log_something('param2 was missing')
        param2 = None

Mit Diktat

value = some_dict.get('some_key', undefined)
if value is None:
    log_something("'some_key' was set to None")

if value is undefined:
    # We know that the dict didn't have 'some_key'
    log_something("'some_key' was not set at all")
    value = None

Mit einem Objekt

value = getattr(obj, 'some_attribute', undefined)
if value is None:
    log_something("'obj.some_attribute' was set to None")
if value is undefined:
    # We know that there's no obj.some_attribute
    log_something("no 'some_attribute' set on obj")
    value = None

Wie ich bereits erwähnt habe, sind benutzerdefinierte Sentinels mit einigen Einschränkungen verbunden. Erstens sind sie keine Schlüsselwörter wie None, also schützt Python sie nicht. Sie können Ihre überschreiben undefined oben jederzeit und überall im Modul, wo es definiert ist, seien Sie also vorsichtig, wie Sie sie verfügbar machen und verwenden. Als nächstes wird die Instanz zurückgegeben von object() ist kein Single. Wenn Sie diesen Anruf 10 Mal machen, erhalten Sie 10 verschiedene Objekte. Schließlich ist die Verwendung eines Sentinels höchst eigenwillig. Ein Sentinel ist spezifisch für die Bibliothek, in der er verwendet wird, und daher sollte sein Geltungsbereich im Allgemeinen auf die Interna der Bibliothek beschränkt sein. Es darf nicht “auslaufen”. Externer Code sollte nur dann darauf aufmerksam werden, wenn er dazu dient, die API der Bibliothek zu erweitern oder zu ergänzen.

  • Was ist mit: None == thing ?

    – hkBst

    1. November 2018 um 9:56 Uhr

  • @hkBst Ich vermute, Ihre Frage bezieht sich darauf, wie Python die Gleichheit auswertet. Schauen Sie sich dies an: http://stackoverflow.com/questions/3588776/…

    – Michael Ekoka

    1. November 2018 um 17:02 Uhr


  • Ah, also IIUC, das normalerweise immer noch Ding anruft.__eq__? In diesem Fall ziehe ich meinen Vorschlag zurück.

    – hkBst

    2. November 2018 um 9:56 Uhr

  • @MichaelEkoka kannst du die Quelle für diese beeindruckenden und nützlichen Informationen teilen.

    – Anidhya Bhatnagar

    25. Dezember 2018 um 6:46 Uhr

  • Standardverfahren. Sie können einige Hinweise darauf finden, wenn Sie durch die gehen Python-Tutorialaber das Lesen des Quellcodes beliebter Projekte ist mein wichtigster Rat, um schnell einzutauchen idiomatische Python.

    – Michael Ekoka

    14. April 2019 um 5:53 Uhr


Es heißt nicht null wie in anderen Sprachen, sondern None. Es gibt immer nur eine Instanz dieses Objekts, mit der Sie auf Äquivalenz prüfen können x is None (Identitätsvergleich) statt x == Nonefalls Sie es wollen.

  • Ich werde einen Weg finden, Python durch erneutes Instanziieren zu brechen None. Dann all diese schlauen Leute, die sich verglichen haben NoneType wird triumphieren!

    – Zenexer

    27. August 2013 um 3:40 Uhr

In Python können Sie das verwenden, um das Fehlen eines Werts darzustellen Keiner Wert (Typen.NoneTyp.None) für Objekte und “” (oder len() == 0) für Streicher. Deswegen:

if yourObject is None:  # if yourObject == None:
    ...

if yourString == "":  # if yourString.len() == 0:
    ...

In Bezug auf den Unterschied zwischen „==“ und „ist“ sollte das Testen der Objektidentität mit „==“ ausreichend sein. Da jedoch die Operation „is“ als Objektidentitätsoperation definiert ist, ist es wahrscheinlich korrekter, sie anstelle von „==“ zu verwenden. Ich bin mir nicht sicher, ob es überhaupt einen Geschwindigkeitsunterschied gibt.

Auf jeden Fall kann man sich anschauen:

Es ergeben sich nur die obigen Antworten True zum Noneaber es gibt so etwas wie float('nan'). Sie könnten Pandas verwenden isnull:

>>> import pandas as pd
>>> pd.isnull(None)
True
>>> pd.isnull(float('nan'))
True
>>> pd.isnull('abc')
False
>>> 

Oder ohne pandas:

>>> a = float('nan')
>>> (a != a) or (a == None)
True
>>> a = None
>>> (a != a) or (a == None)
True
>>> 

Der Grund, warum dies funktioniert, ist, weil float('nan') != float('nan'):

>>> float('nan') == float('nan')
False
>>> float('nan') != float('nan')
True
>>> 

Benutzeravatar von s_mj
s_mj

Verwenden f Zeichenfolge, um dies zu lösen.

year=None
year_val="null" if year is None else  str(year)
print(f'{year_val}')

null

Einfache Funktion, um “leere” Elemente in Python anzugehen:

Code:

def is_empty(element) -> bool:
    """
    Function to check if input `element` is empty.

    Other than some special exclusions and inclusions,
    this function returns boolean result of Falsy check.
    """
    if (isinstance(element, int) or isinstance(element, float)) and element == 0:
        # Exclude 0 and 0.0 from the Falsy set.
        return False
    elif isinstance(element, str) and len(element.strip()) == 0:
        # Include string with one or more empty space(s) into Falsy set.
        return True
    elif isinstance(element, bool):
        # Exclude False from the Falsy set.
        return False
    else:
        # Falsy check.
        return False if element else True

Prüfen:

print("Is empty?\n")
print('"" -> ', is_empty(""))
print('"      " -> ', is_empty("      "))
print('"A" -> ', is_empty("A"))
print('"a" -> ', is_empty("a"))
print('"0" -> ', is_empty("0"))
print("0 -> ", is_empty(0))
print("0.0 -> ", is_empty(0.0))
print("[] -> ", is_empty([]))
print("{} -> ", is_empty({}))
print("() -> ", is_empty(()))
print("[1, 2] -> ", is_empty([1, 2]))
print("(3, 5) -> ", is_empty((3, 5)))
print('{"a": 1} -> ', is_empty({"a": 1}))
print("None -> ", is_empty(None))
print("True -> ", is_empty(True))
print("False -> ", is_empty(False))
print("NaN -> ", is_empty(float("nan")))
print("range(0) -> ", is_empty(range(0)))

Ausgabe:

Is empty?

"" ->  True
"      " ->  True
"A" ->  False
"a" ->  False
"0" ->  False
0 ->  False
0.0 ->  False
[] ->  True
{} ->  True
() ->  True
[1, 2] ->  False
(3, 5) ->  False
{"a": 1} ->  False
None ->  True
True ->  False
False ->  False
NaN ->  False
range(0) ->  True

1400300cookie-checkNull-Objekt in Python

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy