Verwijzend naar het null-object in Python

Hoe verwijs ik naar het null-object in Python?


Antwoord 1, autoriteit 100%

In Python is het ‘null’-object de singleton None.

De beste manier om dingen te controleren op “Niets” is door de identiteitsoperator te gebruiken, is:

if foo is None:
    ...

Antwoord 2, autoriteit 11%

None, Python’s nul?

Er is geen nullin Python; in plaats daarvan is er None. Zoals reeds vermeld, is de meest nauwkeurige manier om te testen of iets Noneals waarde heeft gekregen, het gebruik van de is-identiteitsoperator, die test of twee variabelen naar hetzelfde verwijzen voorwerp.

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

De basis

Er is en kan er maar één zijn None

Noneis de enige instantie van de klasse NoneTypeen alle verdere pogingen om die klasse te instantiëren, zullen hetzelfde object retourneren, waardoor Noneeen eenling. Nieuwkomers in Python zien vaak foutmeldingen die NoneTypevermelden en vragen zich af wat het is. Het is mijn persoonlijke mening dat deze berichten gewoon Nonebij naam kunnen noemen, omdat, zoals we binnenkort zullen zien, Noneweinig ruimte laat voor dubbelzinnigheid. Dus als je een TypeError-bericht ziet waarin staat dat NoneTypedit niet of niet kan doen, weet dan dat het gewoon het ene is Nonedie werd gebruikt op een manier die niet kan.

Bovendien is Noneeen ingebouwde constante. Zodra je Python start, kun je het overal gebruiken, of het nu in module, klasse of functie is. NoneTypedaarentegen is dat niet, je moet er eerst een verwijzing naar krijgen door Nonevoor zijn klasse op te vragen.

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

Je kunt de uniciteit van Nonecontroleren met de identiteitsfunctie van Python id(). Het geeft het unieke nummer terug dat aan een object is toegewezen, elk object heeft er een. Als de id van twee variabelen hetzelfde is, dan wijzen ze in feite naar hetzelfde object.

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

Nonekan niet worden overschreven

In veel oudere versies van Python (vóór 2.4) was het mogelijk om Noneopnieuw toe te wijzen, maar niet meer. Zelfs niet als een klasse-attribuut of binnen de grenzen van een functie.

# 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

Het is daarom veilig om aan te nemen dat alle Nonereferenties hetzelfde zijn. Er is geen “aangepaste” None.

te testen voor NoneGebruik de isoperator

Bij het schrijven van code kunt u in de verleiding komen om te testen voor NONDING zoals deze:

if value==None:
    pass

of om te testen op valsheid als deze

if not value:
    pass

U moet de implicaties begrijpen en waarom het vaak een goed idee is om expliciet te zijn.

Case 1: testen als een waarde is None

Waarom doen

value is None

in plaats van

value==None

?

De eerste is gelijk aan:

id(value)==id(None)

overwegende dat de uitdrukking value==Nonein feite wordt toegepast

value.__eq__(None)

Als de waarde echt is Nonedan krijg je wat je verwachtte.

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

In de meest voorkomende gevallen zal de uitkomst hetzelfde zijn, maar de __eq__()-methode opent een deur die elke garantie voor nauwkeurigheid leegt, omdat het in een klasse kan worden overschreven om speciaal gedrag te bieden.

Overweeg deze klasse.

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

Dus je probeert het op Noneen het werkt

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

Maar dan werkt het ook op de lege string

>>> empty==''
True

En toch

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

Geval 2: Nonegebruiken als boolean

De volgende twee tests

if value:
    # Do something
if not value:
    # Do something

in feite geëvalueerd als

if bool(value):
    # Do something
if not bool(value):
    # Do something

Noneis een “falsey”, wat betekent dat als het naar een boolean wordt gecast, het Falsezal retourneren en als de operator notwordt toegepast, zal het retourneer True. Merk echter op dat het geen eigenschap is die uniek is voor None. Naast Falsezelf, wordt de eigenschap gedeeld door lege lijsten, tuples, sets, dicts, strings, evenals 0, en alle objecten van klassen die de __bool__()magische methode om Falsete retourneren.

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

Dus als je op de volgende manier op variabelen test, let dan extra goed op wat je wel of niet opneemt in de test:

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

Bedoelde u in het bovenstaande dat u init_value()aanroept wanneer de waarde specifiek is ingesteld op None, of bedoelde u dat een waarde is ingesteld op 0, of de lege string, of een lege lijst moet ook de initialisatie activeren? Zoals ik al zei, wees bewust. Zoals vaak het geval is, is in Python expliciet beter dan impliciet.

Nonein de praktijk

Nonegebruikt als signaalwaarde

Noneheeft een speciale status in Python. Het is een favoriete basiswaarde omdat veel algoritmen het als een uitzonderlijke waarde beschouwen. In dergelijke scenario’s kan het worden gebruikt als een vlag om aan te geven dat een voorwaarde een speciale behandeling vereist (zoals het instellen van een standaardwaarde).

U kunt Nonetoewijzen aan de trefwoordargumenten van een functie en er vervolgens expliciet op testen.

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

Je kunt het teruggeven als de standaard wanneer je probeert bij het attribuut van een object te komen en er dan expliciet op testen voordat je iets speciaals doet.

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

Standaard een woordenboek get()methode retourneert Nonebij toegang tot een niet-bestaande sleutel:

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

Als u probeert toegang te krijgen via de subscript-notatie A KeyErrorzou worden verhoogd

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

Evenzo als u probeert een niet-bestaand artikel

te poppen

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

die u kunt onderdrukken met een standaardwaarde die meestal is ingesteld op None

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

Nonegebruikt als zowel een vlag als een geldige waarde

Het hierboven beschreven gebruik van NoneToepassen Wanneer het niet wordt beschouwd als een geldige waarde, maar meer als een signaal om iets bijzonders te doen. Er zijn echter situaties waar het soms belangrijk is om te weten waar Nonevandaan kwam, want hoewel het als een signaal wordt gebruikt, kan het ook deel uitmaken van de gegevens.

Als je een object opvraagt naar zijn attribuut met getattr(some_obj, 'attribute_name', None)en terugkrijgt, vertelt Noneje niet of het attribuut dat je probeerde toegang was ingesteld op Noneof helemaal niet aanwezig was in het object. Dezelfde situatie bij het openen van een sleutel uit een woordenboek, zoals some_dict.get('some_key'), je weet niet of some_dict['some_key']ontbreekt of als het gewoon is ingesteld op None. Als je die informatie nodig hebt, is de gebruikelijke manier om hiermee om te gaan, rechtstreeks proberen toegang te krijgen tot het attribuut of de sleutel vanuit een try/except-constructie:

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)

Vergelijkbaar met 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)

De bovenstaande twee voorbeelden laten zien hoe je object en woordenboek zaken te behandelen. Hoe zit het met de functies? Hetzelfde, maar we gebruiken het dubbele sterretjes keyword argument daartoe:

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"')

Nonealleen gebruikt als een geldige waarde

Als u vindt dat uw code is bezaaid met de bovenstaande try/exceptpatroon gewoon om onderscheid te maken tussen Nonevlaggen en Nonedata, dan gewoon gebruik maken van een andere test waarde. Er is een patroon waarbij een waarde die buiten de verzameling van geldige waarden valt als onderdeel van de gegevens in een datastructuur wordt ingebracht en wordt gebruikt voor controle en proef bijzondere omstandigheden (bijvoorbeeld grenzen, staat, etc.). Dergelijke waarde wordt een sentinel genoemd en kan de weg Nonewordt gebruikt als een signaal worden gebruikt. Het is triviaal om een ​​schildwacht in Python te maken.

undefined = object()

undefinedbovenstaande doel is uniek en doet niet veel van alles wat van belang is voor een programma zou kunnen zijn, het is dus een uitstekende vervanger voor Noneals een vlag . Sommige beperkingen van toepassing, meer over dat na de code.

Met de functie

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

Met dictee

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

Met een object

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

Zoals ik eerder al zei, hebben aangepaste schildwachten een aantal kanttekeningen. Ten eerste zijn het geen trefwoorden zoals None, dus Python beschermt ze niet. Je kunt je undefinedhierboven op elk moment en overal in de module die het is gedefinieerd overschrijven, dus wees voorzichtig met hoe je ze openbaart en gebruikt. Vervolgens is de instantie die wordt geretourneerd door object()geen singleton. Als je die oproep 10 keer doet, krijg je 10 verschillende objecten. Ten slotte is het gebruik van een schildwacht zeer eigenaardig. Een schildwacht is specifiek voor de bibliotheek waarin deze wordt gebruikt en als zodanig moet de reikwijdte ervan over het algemeen worden beperkt tot de interne onderdelen van de bibliotheek. Het mag niet “lekken”. Externe code zou zich er alleen bewust van moeten worden als ze bedoeld zijn om de API van de bibliotheek uit te breiden of aan te vullen.


Antwoord 3, autoriteit 4%

Het wordt niet null genoemd als in andere talen, maar None. Er is altijd slechts één exemplaar van dit object, zodat u kunt controleren op gelijkwaardigheid met x is None(identiteitsvergelijking) in plaats van x == None, als u wilt.


Antwoord 4, Autoriteit 2%

In Python, om de afwezigheid van een waarde weer te geven, kunt u de Geen -waarde (types.nonetype.none ) gebruiken voor objecten en “” (of LEN () == 0 ) voor snaren. Daarom:

if yourObject is None:  # if yourObject == None:
    ...
if yourString == "":  # if yourString.len() == 0:
    ...

Wat betreft het verschil tussen “==” en “is”, testen op objectidentiteit met behulp van “==” moet voldoende zijn. Aangezien de bewerking “is” echter gedefinieerd als de object-identiteitsbewerking, is het waarschijnlijk correcter om het te gebruiken, in plaats van “==”. Ik weet niet zeker of er zelfs een verschil is.

Hoe dan ook, je kunt eens kijken:


Antwoord 5

Gebruik fstring om dit opgelost te krijgen.

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

Antwoord 6

NULL is een speciaal objecttype zoals:

>>>type(None)
<class 'NoneType'>

U kunt controleren of een object in de klasse ‘NONETYPE’ is:

>>>variable = None
>>>variable is None
True

Meer informatie is beschikbaar op python docs


Antwoord 7

per waarheidswaarde testen , ‘Geen ‘Test direct als onwaar, dus de eenvoudigste uitdrukking zal voldoende zijn:

if not foo:

Other episodes