Apa itu nilai None?


130

Saya telah mempelajari Python, dan saya membaca sebuah bab yang menggambarkan Nonenilai, tetapi sayangnya buku ini tidak begitu jelas di beberapa titik. Saya pikir saya akan menemukan jawaban untuk pertanyaan saya, jika saya membagikannya di sana.

Aku ingin tahu apa Nonenilai yang dan apa yang Anda menggunakannya untuk?

Dan juga, saya tidak mendapatkan bagian dari buku ini:

Menetapkan nilai Noneke variabel adalah salah satu cara untuk meresetnya ke keadaan semula, kosong.

Apa artinya?

Jawabannya bagus, meskipun saya tidak mengerti sebagian besar jawaban karena pengetahuan saya yang rendah tentang dunia komputer (saya belum belajar tentang kelas, objek, dll.). Apa arti kalimat ini?

Menetapkan nilai Noneke variabel adalah salah satu cara untuk meresetnya ke keadaan semula, kosong.

Terakhir:

Akhirnya saya mendapat jawaban dari mencari jawaban yang berbeda. Saya harus menghargai semua orang yang memberikan waktu mereka untuk membantu saya (terutama Martijn Pieters dan DSM), dan saya berharap saya dapat memilih semua jawaban sebagai yang terbaik, tetapi pilihannya terbatas pada satu. Semua jawaban sangat bagus.


39
Buku itu tidak terlalu membantu; Nonebukan keadaan kosong default untuk variabel.
Martijn Pieters

Di atas kepala saya, php adalah satu-satunya bahasa yang nilai nolnya setara dengan keadaan kosong default untuk suatu variabel. Sekarang saya bertanya-tanya apa bahasa lain yang melakukan itu.
kojiro

@kojiro perl, meskipun tidak satu pun dari operator kesetaraan senang membandingkan undef. juga bisa dibilang javascript, meskipun memiliki keduanya nulldan undefined.
Eevee

Nilai default variabel javascript @kojiro adalah undefined, jika dibiarkan tidak diinisialisasi.
theouroureye

Benar, yang berbeda dari null, satu hal yang saya gagal berikan pada @MartijnPieters dalam jawabannya.
kojiro

Jawaban:


99

Jawaban Martijn menjelaskan apa yang Noneada di Python, dan dengan benar menyatakan bahwa buku itu menyesatkan. Sejak programmer Python sebagai aturan tidak akan pernah mengatakan

Menetapkan nilai Noneke variabel adalah salah satu cara untuk meresetnya ke keadaan semula, kosong.

sulit untuk menjelaskan apa arti Briggs dengan cara yang masuk akal dan menjelaskan mengapa tidak ada orang di sini yang senang dengan itu. Satu analogi yang dapat membantu:

Dalam Python, nama variabel seperti stiker yang ditempelkan pada objek. Setiap stiker memiliki nama unik yang tertulis di atasnya, dan itu hanya dapat pada satu objek pada satu waktu, tetapi Anda dapat menempatkan lebih dari satu stiker pada objek yang sama, jika Anda mau. Ketika Anda menulis

F = "fork"

Anda menempatkan stiker "F" pada objek string "fork". Jika Anda kemudian menulis

F = None

Anda memindahkan stiker ke Noneobjek.

Apa yang diminta Briggs untuk Anda bayangkan adalah bahwa Anda tidak menulis stiker itu "F", sudah ada Fstiker di situ None, dan yang Anda lakukan hanyalah memindahkannya , dari Noneke "fork". Jadi saat Anda mengetik F = None, Anda "mengatur ulang [ting] ke keadaan semula, keadaan kosong", jika kami memutuskan untuk memperlakukannya Nonesebagai makna empty state.

Saya bisa melihat apa yang dia maksud, tapi itu cara yang buruk untuk melihatnya. Jika Anda memulai Python dan mengetik print(F), Anda tahu

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

dan itu NameErrorberarti Python tidak mengenali namanya F, karena tidak ada stiker seperti itu . Jika Briggs benar dan F = Nonemengatur ulang Fke keadaan semula, maka itu harus ada di sana sekarang, dan kita harus melihat

>>> print(F)
None

seperti yang kita lakukan setelah kita mengetik F = Nonedan memakai stiker None.


Jadi hanya itu yang terjadi. Pada kenyataannya, Python dilengkapi dengan beberapa stiker yang sudah melekat pada objek (nama bawaan), tetapi yang lain Anda harus menulis sendiri dengan garis seperti F = "fork"dan A = 2dan c17 = 3.14, dan kemudian Anda dapat menempelkannya pada objek lain nanti (seperti F = 10atau F = None; itu semua sama .)

Briggs berpura-pura bahwa semua stiker yang mungkin Anda ingin tulis sudah menempel pada Noneobjek.


1
maaf tapi apa maksud Anda dengan Briggs? apakah Anda merujuk pada penulis buku ini? karena namanya adalah Jason R. Briggs.
The_Diver

@The_Diver: ya, itu dia.
DSM

Di mana saya dapat menemukan lebih banyak info tentang nama bawaan Python? Terima kasih.
The_Diver

3
Ini adalah penjelasan yang bagus untuk non-programmer. Terima kasih banyak!
Christina

67

Nonehanyalah nilai yang biasanya digunakan untuk menandakan 'kosong', atau 'tidak ada nilai di sini'. Ini adalah objek sinyal ; itu hanya memiliki makna karena dokumentasi Python mengatakan memiliki makna itu.

Hanya ada satu salinan dari objek itu dalam sesi interpreter Python yang diberikan.

Jika Anda menulis suatu fungsi, dan fungsi itu tidak menggunakan returnpernyataan eksplisit , Nonesebaliknya dikembalikan, misalnya. Dengan begitu, pemrograman dengan fungsi jauh lebih sederhana; suatu fungsi selalu mengembalikan sesuatu , bahkan jika itu hanya satu Noneobjek.

Anda dapat mengujinya secara eksplisit:

if foo is None:
    # foo is set to None

if bar is not None:
    # bar is set to something *other* than None

Penggunaan lain adalah untuk memberikan parameter opsional ke fungsi 'kosong' default:

def spam(foo=None):
    if foo is not None:
        # foo was specified, do something clever!

Fungsi spam()memiliki argumen opsional; jika Anda menelepon spam()tanpa menentukannya, nilai default Nonediberikan padanya, membuatnya mudah untuk mendeteksi apakah fungsi dipanggil dengan argumen atau tidak.

Bahasa lain memiliki konsep serupa. SQL memiliki NULL; JavaScript memiliki undefined dan null , dll.

Perhatikan bahwa dalam Python, variabel ada berdasarkan yang digunakan. Anda tidak perlu mendeklarasikan variabel terlebih dahulu, jadi tidak ada variabel kosong di Python. Mengatur variabel ke Nonekemudian tidak sama dengan mengaturnya ke nilai kosong default; Noneadalah nilai juga, meskipun yang sering digunakan untuk menandakan kekosongan. Buku yang Anda baca menyesatkan tentang hal itu.


1
Saya pikir semantik kekosongan berbeda dari yang tidak terdefinisi . Jadi saya tidak yakin mitra JavaScript dan SQL mengklarifikasi - mereka mungkin membingungkan masalah ini. JavaScript memiliki keduanya undefined dan null .
kojiro

@kojiro: undefinedadalah objek dalam JavaScript, dan Anda dapat menggunakan objek itu secara eksplisit seperti yang dapat Anda gunakan Nonedalam Python. Ini adalah objek sinyal, dengan banyak makna yang sama.
Martijn Pieters

@ Kojiro: SQL bukan bahasa pemrograman, tetapi NULLmasih sesuatu yang dapat ditugaskan dan diuji secara eksplisit.
Martijn Pieters

5
@ MartijnPieters: SQL adalah bahasa pemrograman, hanya tujuan yang sangat spesifik, bersifat deklaratif.
danielkza

3
@daniel: apakah SQL memenuhi syarat sebagai bahasa pemrograman telah menjadi perdebatan panjang ... Lihat stackoverflow.com/questions/900055/… untuk sudut pandang yang menarik.
Martijn Pieters

23

Inilah yang dikatakan dokumentasi Python tentang None:

Nilai tunggal types.NoneType. Tidak ada yang sering digunakan untuk mewakili tidak adanya nilai, seperti ketika argumen default tidak diteruskan ke suatu fungsi.

Diubah dalam versi 2.4: Penugasan untuk Tidak ada yang ilegal dan meningkatkan SyntaxError.

Catatan Nama-nama Tidak Ada dan debug tidak dapat dipindahkan (penugasan kepada mereka, bahkan sebagai nama atribut, meningkatkan SyntaxError), sehingga mereka dapat dianggap sebagai konstanta "benar".

  1. Mari kita konfirmasi jenis yang Nonepertama

    print type(None)
    print None.__class__

    Keluaran

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

Pada dasarnya, NoneTypeadalah tipe data seperti int,, floatdll. Anda dapat memeriksa daftar tipe default yang tersedia di Python di 8.15. jenis - Nama untuk tipe bawaan .

  1. Dan, Noneadalah turunan dari NoneTypekelas. Jadi kita mungkin ingin membuat contoh dari Nonediri kita sendiri. Ayo coba itu

    print types.IntType()
    print types.NoneType()

    Keluaran

    0
    TypeError: cannot create 'NoneType' instances

Jadi jelas, tidak bisa membuat NoneTypeinstance. Kita tidak perlu khawatir tentang keunikan nilainya None.

  1. Mari kita periksa bagaimana kita menerapkannya secara Noneinternal.

    print dir(None)

    Keluaran

    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', 
     '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
     '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

Kecuali __setattr__, semua yang lain adalah atribut hanya-baca. Jadi, tidak ada cara kita dapat mengubah atribut None.

  1. Mari kita coba dan tambahkan atribut baru ke None

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

    Keluaran

    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'

Pernyataan yang terlihat di atas masing-masing menghasilkan pesan kesalahan ini. Artinya, kita tidak dapat membuat atribut secara dinamis pada Noneinstance.

  1. Mari kita periksa apa yang terjadi ketika kita menetapkan sesuatu None. Sesuai dokumentasi, itu harus melempar SyntaxError. Artinya, jika kita menetapkan sesuatu None, program tidak akan dieksekusi sama sekali.

    None = 1

    Keluaran

    SyntaxError: cannot assign to None

Kami telah menetapkan itu

  1. None adalah contoh dari NoneType
  2. None tidak dapat memiliki atribut baru
  3. Atribut yang ada Nonetidak dapat diubah.
  4. Kami tidak dapat membuat contoh lain dari NoneType
  5. Kami bahkan tidak dapat mengubah referensi Nonedengan memberikan nilai padanya.

Jadi, sebagaimana disebutkan dalam dokumentasi, Nonebenar-benar dapat dianggap sebagai a true constant.

Senang mengetahui None:)


Sangat sangat menarik !! satu keraguan apa gunanya __setattr__untuk Tidak Ada
Grijesh Chauhan

9

Buku yang Anda rujuk jelas berusaha sangat menyederhanakan makna None. Variabel Python tidak memiliki keadaan awal, kosong - variabel Python terikat (hanya) ketika mereka didefinisikan . Anda tidak dapat membuat variabel Python tanpa memberinya nilai.

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

tetapi kadang-kadang Anda ingin membuat fungsi memiliki arti yang berbeda tergantung pada apakah suatu variabel didefinisikan atau tidak. Anda dapat membuat argumen dengan nilai default None:

>>> def test(x=None):
...   if x is None:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

Fakta bahwa nilai ini adalah nilai khusus Nonetidak terlalu penting dalam kasus ini. Saya bisa menggunakan nilai default apa pun:

>>> def test(x=-1):
...   if x == -1:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

... tetapi memiliki Nonesekitar memberi kita dua manfaat:

  1. Kami tidak harus memilih nilai khusus seperti -1yang artinya tidak jelas, dan
  2. Fungsi kami mungkin sebenarnya perlu ditangani -1sebagai input normal.
>>> test(-1)
no x here

Ups!

Jadi buku ini sedikit menyesatkan sebagian besar dalam penggunaan kata reset - menugaskan Noneke nama adalah sinyal ke programmer bahwa nilai tersebut tidak digunakan atau bahwa fungsi harus berperilaku dalam beberapa cara standar, tetapi untuk mereset nilai ke keadaan semula dan tidak terdefinisi, Anda harus menggunakan delkata kunci:

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

5

Jawaban lain telah menjelaskan arti Tidak ada yang indah. Namun, saya masih ingin menyoroti ini menggunakan contoh.

Contoh:

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

Sekarang coba tebak output dari daftar di atas. Yah, jawabannya mengejutkan seperti di bawah ini:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

Tapi kenapa?

Banyak yang keliru berharap list1 sama dengan [10] dan list3 sama dengan ['a'] , berpikir bahwa argumen daftar akan disetel ke nilai default [] setiap kali extList dipanggil.

Namun, apa yang sebenarnya terjadi adalah bahwa daftar default baru dibuat hanya sekali ketika fungsi didefinisikan , dan daftar yang sama kemudian digunakan selanjutnya setiap kali extendedList dipanggil tanpa argumen daftar yang ditentukan. Ini karena ekspresi dalam argumen default dihitung ketika fungsi didefinisikan, bukan ketika dipanggil .

list1 dan list3 karenanya beroperasi pada daftar default yang sama, sedangkan list2 beroperasi pada daftar terpisah yang dibuatnya (dengan melewatkan daftar kosongnya sendiri sebagai nilai untuk parameter daftar).


'Tidak ada' penyelamat: (Ubah contoh di atas untuk menghasilkan perilaku yang diinginkan)

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

Dengan implementasi yang direvisi ini, hasilnya adalah:

list1 = [10]
list2 = [123]
list3 = ['a']

Catatan - Contoh kredit ke toptal.com


3

Tidak ada yang merupakan objek tunggal (artinya hanya ada satu Tidak ada), yang digunakan di banyak tempat dalam bahasa dan perpustakaan untuk mewakili tidak adanya nilai lain.


Misalnya:
jika dkamus, d.get(k)akan kembali d[k]jika ada, tetapi Nonejika dtidak memiliki kunci k.

Baca info ini dari blog yang bagus: http://python-history.blogspot.in/


3

Semua ini adalah jawaban yang baik tetapi saya pikir ada lebih banyak untuk menjelaskan mengapa Noneini berguna.

Bayangkan Anda mengumpulkan RSVP untuk pernikahan. Anda ingin mencatat apakah setiap orang akan hadir. Jika mereka hadir, Anda menetapkan person.attending = True. Jika mereka tidak menghadiri set Anda person.attending = False. Jika Anda belum menerima RSVP, maka person.attending = None. Dengan begitu Anda dapat membedakan antara tidak ada informasi - None- dan jawaban negatif.


1

Saya suka contoh kode (juga buah), jadi saya tunjukkan

apple = "apple"
print(apple)
>>> apple
apple = None
print(apple)
>>> None

Tidak ada yang berarti, itu tidak memiliki nilai.

Tidak ada yang menilai False.


8
print(None)cetakan .. None. Itu tidak tidak , seperti yang Anda sarankan, cetak apa-apa.
Martijn Pieters

REPL hanya menunjukkan apa-apa karena Noneitu adalah hasil dari ekspresi terakhir. (yang sebagian besar bermanfaat untuk fungsi yang tidak dimaksudkan untuk mengembalikan nilai.)
Eevee

Eugh, kesalahan saya, saya menggunakan IDLE dan saya berasumsi itu mencetak variabel, ternyata itu menggunakan repl. Saat ini saya menggunakan SO untuk menyempurnakan keterampilan membaca & memahami python / javascript / kode saya sendiri, jadi saya membuat beberapa kesalahan :(
Azeirah

2
IDLE, seperti prompt interpreter interaktif Python, secara eksplisit menyembunyikan None jika itu adalah hasil dari ekspresi, kebanyakan untuk tidak mengacaukan output.
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 
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.