Uczyłem się Pythona i przeczytałem rozdział, który opisuje None
wartość, ale niestety ta książka nie jest w niektórych punktach zbyt jasna. Pomyślałem, że znajdę odpowiedź na swoje pytanie, jeśli się tam podzielę.
Chcę wiedzieć, jaka jestNone
wartość i do czego go używasz?
Nie rozumiem też tej części książki:
Przypisanie wartości
None
zmiennej jest jednym ze sposobów przywrócenia jej do pierwotnego, pustego stanu.
Co to znaczy?
Odpowiedzi były świetne, chociaż większości odpowiedzi nie rozumiałem ze względu na moją niską znajomość świata komputerów (nie poznałem zajęć, przedmiotów itp.). Co to zdanie oznacza?
Przypisanie wartości
None
zmiennej jest jednym ze sposobów przywrócenia jej do pierwotnego, pustego stanu.
Finał:
Wreszcie otrzymałem odpowiedź, szukając różnych odpowiedzi. Muszę docenić wszystkich ludzi, którzy poświęcili mi swój czas (zwłaszcza Martijn Pieters i DSM) i chciałbym móc wybrać wszystkie odpowiedzi jako najlepsze, ale wybór jest ograniczony do jednej. Wszystkie odpowiedzi były świetne.
źródło
None
nie jest domyślnym pustym stanem dla zmiennych.undef
. także prawdopodobnie javascript, choć ma zarównonull
iundefined
.undefined
, jeśli nie została zainicjowana.null
kwestia, której nie przekazuję @MartijnPieters w jego odpowiedzi.Odpowiedzi:
Odpowiedź Martijna wyjaśnia, co
None
jest w Pythonie i poprawnie stwierdza, że książka wprowadza w błąd. Ponieważ programiści Pythona z reguły nigdy by tego nie powiedzieliTrudno jest wyjaśnić, co ma na myśli Briggs w sposób, który ma sens i wyjaśnia, dlaczego nikt tutaj nie wydaje się być z tego zadowolony. Jedna analogia, która może pomóc:
W Pythonie nazwy zmiennych są jak naklejki nakładane na obiekty. Każda naklejka ma wypisaną unikalną nazwę i może znajdować się tylko na jednym przedmiocie naraz, ale możesz umieścić więcej niż jedną naklejkę na tym samym przedmiocie, jeśli chcesz. Kiedy piszesz
F = "fork"
umieszczasz naklejkę "F" na obiekcie typu string
"fork"
. Jeśli napiszeszF = None
przesuwasz naklejkę na
None
obiekt.Co Briggs prosi cię do wyobrażenia jest, aby nie pisać naklejkę
"F"
, nie było jużF
naklejki naNone
, a wszystko co robił było przenieść go odNone
do"fork"
. Więc kiedy piszeszF = None
, „resetujesz [ting] do pierwotnego, pustego stanu”, jeśli zdecydowaliśmy się traktować toNone
jako znaczenieempty state
.Widzę, do czego zmierza, ale to zły sposób patrzenia na to. Jeśli uruchomisz Pythona i wpiszesz
print(F)
, zobaczysz>>> print(F) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'F' is not defined
a to
NameError
oznacza, że Python nie rozpoznaje nazwyF
, ponieważ nie ma takiej naklejki . Jeśli Briggs miał rację iF = None
resetuje sięF
do swojego pierwotnego stanu, to powinien tam być teraz i powinniśmy zobaczyć>>> print(F) None
tak jak robimy to po wpisaniu
F = None
i naklejeniu naklejkiNone
.Więc to wszystko, co się dzieje. W rzeczywistości Python zawiera kilka naklejek już dołączonych do obiektów (wbudowane nazwy), ale inne musisz napisać samemu liniami takimi jak
F = "fork"
iA = 2
ic17 = 3.14
, a następnie możesz przykleić je później na innych obiektach (np.F = 10
LubF = None
; to wszystko to samo .)Briggs udaje, że wszystkie możliwe naklejki, które chciałbyś napisać, zostały już przyklejone do
None
obiektu.źródło
None
jest po prostu wartością, która jest często używana do oznaczenia „pustego” lub „braku wartości”. Jest to obiekt sygnałowy ; ma znaczenie tylko dlatego, że dokumentacja Pythona mówi, że ma to znaczenie.Istnieje tylko jedna kopia tego obiektu w danej sesji interpretera Pythona.
Jeśli napiszesz funkcję, a ta funkcja nie używa jawnej
return
instrukcji,None
zostanie na przykład zwrócona. W ten sposób programowanie z funkcjami jest znacznie uproszczone; funkcja zawsze zwraca coś , nawet jeśli jest to tylko ten jedenNone
obiekt.Możesz to sprawdzić jawnie:
if foo is None: # foo is set to None if bar is not None: # bar is set to something *other* than None
Innym zastosowaniem jest nadanie opcjonalnym parametrom funkcji „pustej” wartości domyślnej:
def spam(foo=None): if foo is not None: # foo was specified, do something clever!
Funkcja
spam()
ma opcjonalny argument; jeśli zadzwoniszspam()
bez określenia tego,None
zostanie mu przypisana wartość domyślna , ułatwiając wykrycie, czy funkcja została wywołana z argumentem, czy nie.Inne języki mają podobne koncepcje. SQL ma
NULL
; JavaScript maundefined
inull
itp.Zauważ, że w Pythonie zmienne istnieją ze względu na ich użycie. Nie musisz najpierw deklarować zmiennej, więc w Pythonie nie ma naprawdę pustych zmiennych. Ustawienie zmiennej na
None
to nie to samo, co ustawienie domyślnej pustej wartości;None
jest również wartością, aczkolwiek taką, która jest często używana do sygnalizowania pustki. Książka, którą czytasz, wprowadza w błąd w tej kwestii.źródło
undefined
inull
.undefined
jest obiektem w JavaScript i możesz używać tego obiektu jawnie, tak jakNone
w Pythonie. Jest to obiekt sygnałowy o podobnym znaczeniu.NULL
nadal jest czymś, co można jednoznacznie przypisać i przetestować.Oto, co ma do powiedzenia dokumentacja Pythona
None
:Potwierdźmy typ
None
pierwszegoprint type(None) print None.__class__
Wynik
<type 'NoneType'> <type 'NoneType'>
Zasadniczo
NoneType
jest to typ danych taki jakint
,float
itp. Możesz sprawdzić listę domyślnych typów dostępnych w Pythonie w 8.15. typy - nazwy typów wbudowanych .I,
None
jest przykłademNoneType
klasy. Więc możemy chcieć stworzyć własne instancjeNone
. Spróbujmy tegoprint types.IntType() print types.NoneType()
Wynik
0 TypeError: cannot create 'NoneType' instances
Tak więc wyraźnie nie mogę tworzyć
NoneType
instancji. Nie musimy martwić się o wyjątkowość wartościNone
.Sprawdźmy, jak wdrożyliśmy
None
wewnętrznie.print dir(None)
Wynik
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Z wyjątkiem
__setattr__
wszystkich innych atrybutów tylko do odczytu. Nie ma więc możliwości zmiany atrybutówNone
.Spróbujmy dodać nowe atrybuty do
None
setattr(types.NoneType, 'somefield', 'somevalue') setattr(None, 'somefield', 'somevalue') None.somefield = 'somevalue'
Wynik
Powyższe instrukcje generują odpowiednio te komunikaty o błędach. Oznacza to, że nie możemy dynamicznie tworzyć atrybutów w pliku
None
instancji.Sprawdźmy, co się stanie, gdy coś przypiszemy
None
. Zgodnie z dokumentacją powinien wyrzucić plikSyntaxError
. To znaczy, jeśli przypisujemy coś doNone
, program w ogóle nie zostanie wykonany.None = 1
Wynik
SyntaxError: cannot assign to None
Ustaliliśmy to
None
jest przykłademNoneType
None
nie może mieć nowych atrybutówNone
nie można zmienić.NoneType
None
, przypisując mu wartości.Tak więc, jak wspomniano w dokumentacji,
None
można naprawdę uznać za pliktrue constant
.Miłej wiedzy
None
:)źródło
__setattr__
Książka, do której się odnosisz, wyraźnie stara się znacznie uprościć znaczenie
None
. Zmienne Pythona nie mają początkowego, pustego stanu - zmienne Pythona są powiązane (tylko), gdy są zdefiniowane . Nie możesz utworzyć zmiennej Pythona bez nadania jej wartości.>>> 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
ale czasami chcesz, aby funkcja miała różne znaczenie w zależności od tego, czy zmienna jest zdefiniowana, czy nie. Możesz utworzyć argument z domyślną wartością
None
:>>> def test(x=None): ... if x is None: ... print('no x here') ... else: ... print(x) ... >>> test() no x here >>> test('x!') x!
Fakt, że ta wartość jest wartością specjalną,
None
nie jest w tym przypadku szczególnie ważny. Mogłem użyć dowolnej wartości domyślnej:>>> def test(x=-1): ... if x == -1: ... print('no x here') ... else: ... print(x) ... >>> test() no x here >>> test('x!') x!
… Ale posiadanie w
None
pobliżu daje nam dwie korzyści:-1
której znaczenie jest niejasne i-1
jak normalne dane wejściowe.>>> test(-1) no x here
ups!
Więc książka jest trochę myląca, głównie w używaniu słowa reset - przypisanie
None
do nazwy jest sygnałem dla programisty, że ta wartość nie jest używana lub że funkcja powinna zachowywać się w jakiś domyślny sposób, ale aby zresetować wartość do pierwotnego, niezdefiniowanego stanu, musisz użyćdel
słowa kluczowego:>>> x = 3 >>> x 3 >>> del x >>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined
źródło
Inne odpowiedzi już pięknie wyjaśniły znaczenie Żaden . Chciałbym jednak rzucić więcej światła na ten temat na przykładzie.
Przykład:
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
Teraz spróbuj odgadnąć wynik powyższej listy. Cóż, odpowiedź jest zaskakująca jak poniżej:
list1 = [10, 'a'] list2 = [123] list3 = [10, 'a']
Ale dlaczego?
Wielu błędnie spodziewa się, że lista1 będzie równa [10], a lista3 będzie równa ['a'] , myśląc, że argument listy zostanie ustawiony na domyślną wartość [] za każdym razem, gdy wywoływana jest funkcja extList.
Jednak w rzeczywistości nowa lista domyślna jest tworzona tylko raz, gdy funkcja jest zdefiniowana , a ta sama lista jest następnie używana za każdym razem, gdy wywoływana jest funkcja extList bez podania argumentu listy. Dzieje się tak, ponieważ wyrażenia w argumentach domyślnych są obliczane podczas definiowania funkcji, a nie podczas jej wywoływania .
lista1 i lista3 działają zatem na tej samej domyślnej liście, podczas gdy lista2 działa na osobnej liście, którą utworzyła (przekazując własną pustą listę jako wartość parametru listy).
`` Brak '' zbawiciela: (Zmodyfikuj powyższy przykład, aby uzyskać pożądane zachowanie)
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
Dzięki tej poprawionej implementacji wynik będzie następujący:
list1 = [10] list2 = [123] list3 = ['a']
Uwaga - przykładowy kredyt dla toptal.com
źródło
None jest pojedynczym obiektem (co oznacza, że jest tylko jeden None), używanym w wielu miejscach w języku i bibliotece do reprezentowania braku innej wartości.
Na przykład:
if
d
jest słownikiem,d.get(k)
zwróci,d[k]
jeśli istnieje, aleNone
jeślid
nie ma kluczak
.Przeczytaj te informacje ze świetnego bloga: http://python-history.blogspot.in/
źródło
Wszystkie te odpowiedzi są dobre, ale myślę, że jest więcej do wyjaśnienia, dlaczego
None
jest to przydatne.Wyobraź sobie, że zbierasz zaproszenia na wesele. Chcesz nagrać, czy każda osoba weźmie udział. Jeśli oni wezmą udział, ty ustaw
person.attending = True
. Jeśli nie przyjdą, ustawperson.attending = False
. Jeśli nie otrzymałeś żadnej RSVP, toperson.attending = None
. W ten sposób możesz odróżnić brak informacji -None
- od odpowiedzi negatywnej.źródło
Uwielbiam przykłady kodu (a także owoce), więc pozwól, że ci pokażę
apple = "apple" print(apple) >>> apple apple = None print(apple) >>> None
Nic nie znaczy nic, nie ma wartości.
None ma wartość False.
źródło
print(None)
wydruki ..None
. Czyni nie , jak sugerują, drukowania nic.None
wtedy, gdy jest wynikiem ostatniego wyrażenia. (co jest głównie przydatne w przypadku funkcji, które nie mają zwracać wartości).None
jeśli jest to wynikiem wyrażenia, głównie po to, aby nie zaśmiecać danych wyjściowych.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
źródło