Co to jest wartość Brak?


135

Uczyłem się Pythona i przeczytałem rozdział, który opisuje Nonewartość, 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 Nonezmiennej 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 Nonezmiennej 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.


40
Ta książka nie jest zbyt pomocna; Nonenie jest domyślnym pustym stanem dla zmiennych.
Martijn Pieters

Poza tym php jest jedynym językiem, którego wartość null jest równoważna domyślnemu pustemu stanowi zmiennej. Teraz zastanawiam się, jakie inne języki to robią.
kojiro

@kojiro perl, chociaż żaden z operatorów równości nie jest zadowolony z porównania z undef. także prawdopodobnie javascript, choć ma zarówno nulli undefined.
Eevee

Domyślną wartością zmiennej javascript @kojiro jest undefined, jeśli nie została zainicjowana.
thefourtheye

Racja, co jest inne niż nullkwestia, której nie przekazuję @MartijnPieters w jego odpowiedzi.
kojiro

Odpowiedzi:


103

Odpowiedź Martijna wyjaśnia, co Nonejest w Pythonie i poprawnie stwierdza, że ​​książka wprowadza w błąd. Ponieważ programiści Pythona z reguły nigdy by tego nie powiedzieli

Przypisanie wartości Nonezmiennej jest jednym ze sposobów przywrócenia jej do pierwotnego, pustego stanu.

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

F = None

przesuwasz naklejkę na Noneobiekt.

Co Briggs prosi cię do wyobrażenia jest, aby nie pisać naklejkę "F", nie było jużF naklejki na None, a wszystko co robił było przenieść go od Nonedo"fork" . Więc kiedy piszesz F = None, „resetujesz [ting] do pierwotnego, pustego stanu”, jeśli zdecydowaliśmy się traktować to Nonejako znaczenie empty state.

Widzę, do czego zmierza, ale to zły sposób patrzenia na to. Jeśli uruchomisz Pythona i wpiszeszprint(F) , zobaczysz

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

a to NameErroroznacza, że Python nie rozpoznaje nazwy F, ponieważ nie ma takiej naklejki . Jeśli Briggs miał rację i F = Noneresetuje 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 = Nonei 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"i A = 2i c17 = 3.14, a następnie możesz przykleić je później na innych obiektach (np.F = 10 Lub F = None; to wszystko to samo .)

Briggs udaje, że wszystkie możliwe naklejki, które chciałbyś napisać, zostały już przyklejone do Noneobiektu.


1
przepraszam, ale co masz na myśli mówiąc Briggs? czy odnosisz się do autora tej książki? ponieważ nazywa się Jason R. Briggs.
The_Diver

@The_Diver: tak, to on.
DSM,

Gdzie mogę znaleźć więcej informacji o nazwach wbudowanych w Pythonie? Dzięki.
The_Diver

3
To świetne wytłumaczenie dla nie programisty. Dziękuję Ci bardzo!
Christina

70

Nonejest 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 returninstrukcji, Nonezostanie 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 jeden Noneobiekt.

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, Nonezostanie 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 ma undefined i null 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 Noneto nie to samo, co ustawienie domyślnej pustej wartości; Nonejest 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.


1
Myślę, że semantyka pustki różni się od semantyki nieokreśloności . Więc nie jestem pewien, czy odpowiedniki JavaScript i SQL wyjaśniają - mogą zmylić problem. JavaScript ma zarówno undefined i null .
kojiro

@kojiro: undefinedjest obiektem w JavaScript i możesz używać tego obiektu jawnie, tak jak Nonew Pythonie. Jest to obiekt sygnałowy o podobnym znaczeniu.
Martijn Pieters

@kojiro: SQL nie jest językiem programowania, ale NULLnadal jest czymś, co można jednoznacznie przypisać i przetestować.
Martijn Pieters

5
@MartijnPieters: SQL to język programowania, po prostu bardzo specyficzny, deklaratywny.
danielkza

3
@daniel: kastrowanych kwalifikuje SQL jako język programowania była długa debata ... zobacz stackoverflow.com/questions/900055/... ciekawych ujęć.
Martijn Pieters

25

Oto, co ma do powiedzenia dokumentacja PythonaNone :

Jedyna wartość types.NoneType. Brak jest często używany do reprezentowania braku wartości, tak jak wtedy, gdy domyślne argumenty nie są przekazywane do funkcji.

Zmieniono w wersji 2.4: przypisania do None są niedozwolone i powodują błąd SyntaxError.

Uwaga Nazwy None i debug nie mogą być ponownie przypisane (przypisania do nich, nawet jako nazwa atrybutu, wywołują błąd SyntaxError), więc można je uznać za stałe „prawdziwe”.

  1. Potwierdźmy typ Nonepierwszego

    print type(None)
    print None.__class__
    

    Wynik

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

Zasadniczo NoneTypejest to typ danych taki jak int, floatitp. Możesz sprawdzić listę domyślnych typów dostępnych w Pythonie w 8.15. typy - nazwy typów wbudowanych .

  1. I, None jest przykładem NoneTypeklasy. Więc możemy chcieć stworzyć własne instancje None. Spróbujmy tego

    print 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ści None.

  1. 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ów None.

  1. Spróbujmy dodać nowe atrybuty do None

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

    Wynik

    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'
    

Powyższe instrukcje generują odpowiednio te komunikaty o błędach. Oznacza to, że nie możemy dynamicznie tworzyć atrybutów w plikuNone instancji.

  1. Sprawdźmy, co się stanie, gdy coś przypiszemy None. Zgodnie z dokumentacją powinien wyrzucić plik SyntaxError. 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

  1. None jest przykładem NoneType
  2. None nie może mieć nowych atrybutów
  3. Istniejące atrybuty None nie można zmienić.
  4. Nie możemy tworzyć innych instancji NoneType
  5. Nie możemy nawet zmienić odniesienia do None, przypisując mu wartości.

Tak więc, jak wspomniano w dokumentacji, Nonemożna naprawdę uznać za pliktrue constant .

Miłej wiedzy None:)


Bardzo, bardzo interesujące !! wątpię, co jest __setattr__
pożyteczne

11

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ą, Nonenie 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 Nonepobliżu daje nam dwie korzyści:

  1. Nie musimy wybierać specjalnej wartości, na przykład -1której znaczenie jest niejasne i
  2. Nasza funkcja może faktycznie wymagać obsługi -1jak 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 Nonedo 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ć delsł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

6

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


3

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 djest słownikiem, d.get(k)zwróci, d[k]jeśli istnieje, ale Nonejeśli dnie ma klucza k.

Przeczytaj te informacje ze świetnego bloga: http://python-history.blogspot.in/


3

Wszystkie te odpowiedzi są dobre, ale myślę, że jest więcej do wyjaśnienia, dlaczego Nonejest 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ą, ustaw person.attending = False. Jeśli nie otrzymałeś żadnej RSVP, to person.attending = None. W ten sposób możesz odróżnić brak informacji - None- od odpowiedzi negatywnej.


1

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.


8
print(None)wydruki .. None. Czyni nie , jak sugerują, drukowania nic.
Martijn Pieters

REPL nie pokazuje nic tylko Nonewtedy, gdy jest wynikiem ostatniego wyrażenia. (co jest głównie przydatne w przypadku funkcji, które nie mają zwracać wartości).
Eevee

Eugh, mój błąd, używałem IDLE i założyłem, że wypisuje zmienne, najwyraźniej używa repl. Obecnie używam SO do doskonalenia własnych umiejętności czytania i rozumienia kodu Python / javascript / kodu, więc popełniam kilka błędów :(
Azeirah

2
IDLE, podobnie jak zachęta interaktywnego interpretera Pythona, wyraźnie ukrywa, None jeśli jest to wynikiem wyrażenia, głównie po to, aby nie zaśmiecać danych wyjściowych.
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 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.