Jak odwoływać się do obiektu zerowego w Pythonie?
1190
W Pythonie „zerowym” obiektem jest singleton None
.
Najlepszym sposobem sprawdzenia rzeczy pod kątem „Noneness” jest użycie operatora tożsamości is
:
if foo is None:
...
egg is None
przezegg == None
: Te ostatnie mogą być przeciążone, a może złamać przy porównywaniu ważny obiekt z None (w zależności od tego, jak to jest realizowane, ale nie należy się spodziewać, wszyscy wziąć Porównania z Żaden pod uwagę, prawda?) , podczas gdyis
zawsze działa tak samo.None
Python jest zerowy?W
null
Pythonie nie maNone
. Jak już wspomniano, najdokładniejszym sposobem sprawdzenia, czy coś zostało podaneNone
jako wartość, jest użycieis
operatora tożsamości, który sprawdza, czy dwie zmienne odnoszą się do tego samego obiektu.Podstawy
Jest i może być tylko jeden
None
None
jest jedyną instancją klasyNoneType
i wszelkie dalsze próby utworzenia tej klasy zwrócą ten sam obiekt, co spowodujeNone
utworzenie singletonu. Nowi użytkownicy Pythona często widzą komunikaty o błędach, które wspominająNoneType
i zastanawiają się, co to jest. Moim osobistym zdaniem te wiadomości mogą po prostu wspomniećNone
po imieniu, ponieważ, jak zobaczymy wkrótce,None
pozostawia niewiele miejsca na dwuznaczność. Więc jeśli zobaczysz jakieśTypeError
przesłanie, które wspomina, żeNoneType
nie może tego zrobić lub nie może tego zrobić, po prostu wiedz, że to po prostu taki,None
który był używany w sposób, którego nie może.Ponadto
None
jest wbudowaną stałą, gdy tylko uruchamiasz Python, można go używać z dowolnego miejsca, czy to w module, klasie czy funkcji.NoneType
w przeciwieństwie do tego nie trzeba, najpierw trzeba by się do niego odwołać, sprawdzającNone
jego klasę.Możesz sprawdzić
None
unikalność za pomocą funkcji tożsamości Pythonaid()
. Zwraca unikalny numer przypisany do obiektu, każdy obiekt ma jeden. Jeśli identyfikator dwóch zmiennych jest taki sam, to w rzeczywistości wskazują na ten sam obiekt.None
nie można zastąpićW dużo starszej wersji Pythona (wcześniejszej niż 2.4) możliwe było ponowne przypisanie
None
, ale już nie. Nawet jako atrybut klasy lub w ramach funkcji.Dlatego można bezpiecznie założyć, że wszystkie
None
odniesienia są takie same. Nie ma „niestandardowego”None
.Aby przetestować
None
użycieis
operatoraPodczas pisania kodu możesz ulec pokusie przetestowania Noneness w następujący sposób:
Lub przetestować pod kątem fałszu w ten sposób
Musisz zrozumieć konsekwencje i dlaczego często dobrym pomysłem jest mówienie wprost.
Przypadek 1: sprawdzenie, czy wartość ma wartość
None
czemu to robić
zamiast
Pierwszy jest równoważny z:
Podczas gdy wyrażenie
value==None
jest w rzeczywistości stosowane w ten sposóbjeśli wartość jest naprawdę
None
, otrzymasz to, czego się spodziewałeś.W najczęstszych przypadkach wynik będzie taki sam, ale
__eq__()
metoda otwiera drzwi, które unieważniają jakąkolwiek gwarancję dokładności, ponieważ można ją zastąpić w klasie, aby zapewnić specjalne zachowanie.Rozważ tę klasę.
Więc wypróbuj
None
i działaAle potem działa również na pusty ciąg
I jeszcze
Przypadek 2: Używanie
None
jako wartości logicznejNastępne dwa testy
są w rzeczywistości oceniane jako
None
jest „falsey”, co oznacza, że jeśli zostanie ustawiony na wartość logiczną, zwróciFalse
i jeśli zastosujenot
operator, zwróciTrue
. Pamiętaj jednak, że nie jest to właściwość unikalna dlaNone
. OpróczFalse
siebie właściwość jest wspólna dla pustych list, krotek, zestawów, dykt, ciągów, a także 0 i wszystkich obiektów z klas, które implementują__bool__()
magiczną metodę powrotuFalse
.Dlatego podczas testowania zmiennych w następujący sposób zwracaj szczególną uwagę na to, co włączasz lub wyłączasz z testu:
W powyższym przypadku, czy chciałeś zadzwonić,
init_value()
gdy wartość jest ustawiona konkretnie naNone
, czy miałeś na myśli, że wartość ustawiona na0
, pusty ciąg znaków lub pusta lista powinna również inicjować inicjalizację. Tak jak powiedziałem, bądź ostrożny. Jak to często bywa w Pythonie, jawne jest lepsze niż niejawne .None
w praktyceNone
używany jako wartość sygnałuNone
ma specjalny status w Pythonie. Jest to ulubiona wartość wyjściowa, ponieważ wiele algorytmów traktuje ją jako wartość wyjątkową. W takich scenariuszach można go użyć jako flagi, aby zasygnalizować, że warunek wymaga specjalnej obsługi (np. Ustawienia wartości domyślnej).Możesz przypisać
None
argumentom słowa kluczowego funkcji, a następnie jawnie ją przetestować.Możesz przywrócić go jako domyślny, gdy próbujesz dostać się do atrybutu obiektu, a następnie jawnie go przetestować przed zrobieniem czegoś specjalnego.
Domyślnie
get()
metoda słownika powracaNone
podczas próby uzyskania dostępu do nieistniejącego klucza:Jeśli spróbujesz uzyskać do niego dostęp za pomocą notacji indeksu dolnego
KeyError
, zostanie podniesionyPodobnie jeśli spróbujesz rozbić nieistniejący element
które można ukryć za pomocą domyślnej wartości, która zwykle jest ustawiona na
None
None
używany zarówno jako flaga, jak i poprawna wartośćOpisane powyżej zastosowania
None
mają zastosowanie, gdy nie jest uważane za prawidłową wartość, ale bardziej przypomina sygnał do zrobienia czegoś specjalnego. Są jednak sytuacje, w których czasem ważne jest, aby wiedzieć, skądNone
pochodzi, ponieważ nawet jeśli jest używany jako sygnał, może również stanowić część danych.Kiedy pytasz obiekt o jego atrybut z
getattr(some_obj, 'attribute_name', None)
powrotemNone
, nie mówi ci, czy atrybut, do którego próbujesz uzyskać dostęp, został ustawiony,None
czy też był całkowicie nieobecny w obiekcie. Ta sama sytuacja podczas uzyskiwania dostępu do klucza ze słownika, np.some_dict.get('some_key')
Nie wiesz, czy gosome_dict['some_key']
brakuje, czy po prostu jest ustawiony naNone
. Jeśli potrzebujesz tych informacji, zwykłym sposobem radzenia sobie z nimi jest bezpośrednia próba uzyskania dostępu do atrybutu lub klucza z poziomutry/except
konstrukcji:Podobnie z dict:
Powyższe dwa przykłady pokazują, jak obsługiwać przypadki obiektów i słowników, a co z funkcjami? To samo, ale w tym celu używamy argumentu słowa kluczowego podwójnej gwiazdki:
None
używane tylko jako poprawna wartośćJeśli stwierdzisz, że Twój kod jest zaśmiecony powyższym
try/except
wzorcem, aby odróżnićNone
flagi iNone
dane, użyj innej wartości testowej. Istnieje wzorzec, w którym wartość, która nie mieści się w zestawie prawidłowych wartości, jest wstawiana jako część danych w strukturze danych i służy do kontrolowania i testowania warunków specjalnych (np. Granic, stanu itp.). Taką wartość nazywa się wartownikiem i można ją wykorzystać tak,None
jak sygnał. Utworzenie wartownika w Pythonie jest banalne.Powyższy
undefined
obiekt jest wyjątkowy i nie robi nic, co mogłoby zainteresować program, dlatego jest doskonałym zamiennikiemNone
jako flaga. Obowiązują pewne zastrzeżenia, więcej o tym po kodzie.Z funkcją
Z dyktando
Z przedmiotem
Jak wspomniałem wcześniej, niestandardowi strażnicy mają pewne zastrzeżenia. Po pierwsze, nie są one słowami kluczowymi
None
, więc Python ich nie chroni. Możesz zastąpićundefined
powyższe w dowolnym momencie, w dowolnym miejscu w module, który jest zdefiniowany, więc bądź ostrożny, jak je ujawnić i używać. Następnie instancja zwrócona przezobject()
nie jest singletonem, jeśli wykonasz to wywołanie 10 razy, otrzymasz 10 różnych obiektów. Wreszcie użycie wartownika jest bardzo idiosynkratyczne. Wartownik jest specyficzny dla biblioteki, w której jest używany i jako taki, jego zakres powinien zasadniczo być ograniczony do wewnętrznych elementów biblioteki. Nie powinien „wyciec”. Kod zewnętrzny powinien wiedzieć o tym tylko, jeśli ich celem jest rozszerzenie lub uzupełnienie interfejsu API biblioteki.źródło
Nazywa się nie zerowy jak w innych językach, ale
None
. Zawsze jest tylko jedna instancja tego obiektu, więc możesz sprawdzić równoważność zx is None
(porównanie tożsamości) zamiastx == None
, jeśli chcesz.źródło
None
. Wtedy wszyscy mądrzy ludzie, którzy porównali się z nimiNoneType
, zatriumfują!W Pythonie, aby reprezentować brak wartości, możesz użyć wartości None ( types.NoneType.None ) dla obiektów i „” (lub len () == 0 ) dla łańcuchów. W związku z tym:
Jeśli chodzi o różnicę między „==” a „is”, wystarczające powinno być sprawdzenie tożsamości obiektu za pomocą „==”. Ponieważ jednak operacja „jest” jest zdefiniowana jako operacja tożsamości obiektu, prawdopodobnie bardziej poprawne jest użycie jej niż „==”. Nie jestem pewien, czy występuje nawet różnica prędkości.
W każdym razie możesz spojrzeć na:
źródło
0 == false
zwracatrue
się tak, ponieważ dwukrotnie równa operator wykonuje typu przymus. Jednak z operatorem triple-equals0 === false
zwraca wartośćfalse
, ponieważ „liczba” i „wartość logiczna” są różnymi typami.true
warunkowo. W Rust and Go,0
ifalse
są różne typy, które nie mogą być porównywane dla równości.Null to specjalny typ obiektu, taki jak:
Możesz sprawdzić, czy obiekt należy do klasy „NoneType”:
Więcej informacji jest dostępnych w Python Docs
źródło
W przypadku testowania wartości według prawdy „Brak” testuje bezpośrednio jako FAŁSZ, więc wystarczy najprostsze wyrażenie:
źródło
True
do dowolnej wartości falsy nie tylkoNone
.