Jawaban:
Dalam Python, objek 'null' adalah singleton None.
Cara terbaik untuk memeriksa hal-hal untuk "Noneness" adalah dengan menggunakan operator identitas, is:
if foo is None:
...
None, Python nol?Tidak ada nulldalam Python, melainkan ada None. Seperti yang telah dinyatakan, cara paling akurat untuk menguji bahwa sesuatu telah diberi Nonenilai adalah dengan menggunakan isoperator identitas, yang menguji dua variabel yang merujuk ke objek yang sama.
>>> foo is None
True
>>> foo = 'bar'
>>> foo is None
False
NoneNoneadalah satu-satunya instance dari kelas NoneTypedan setiap upaya lebih lanjut dalam membuat instance kelas yang akan mengembalikan objek yang sama, yang membuat Nonesingleton. Pendatang baru di Python sering melihat pesan kesalahan yang menyebutkan NoneTypedan bertanya-tanya apa itu. Ini adalah pendapat pribadi saya bahwa pesan-pesan ini hanya bisa disebutkan Nonenamanya saja, karena, seperti yang akan kita lihat sebentar lagi, Nonemenyisakan sedikit ruang bagi ambiguitas. Jadi, jika Anda melihat beberapa TypeErrorpesan yang menyebutkan bahwa NoneTypetidak dapat melakukan ini atau tidak dapat melakukannya, ketahuilah bahwa itu hanyalah pesan Noneyang digunakan dengan cara yang tidak dapat dilakukan.
Juga, Noneadalah konstanta bawaan, segera setelah Anda memulai Python tersedia untuk digunakan dari mana saja, baik dalam modul, kelas, atau fungsi. NoneTypesebaliknya tidak, Anda harus mendapatkan referensi terlebih dahulu dengan menanyakan Nonekelasnya.
>>> NoneType
NameError: name 'NoneType' is not defined
>>> type(None)
NoneType
Anda dapat memeriksa Nonekeunikan dengan fungsi identitas Python id(). Ini mengembalikan nomor unik yang ditetapkan untuk suatu objek, masing-masing objek memiliki satu. Jika id dari dua variabel sama, maka mereka menunjuk ke objek yang sama.
>>> 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
None tidak dapat ditimpaDalam versi Python yang jauh lebih lama (sebelum 2.4) dimungkinkan untuk ditugaskan kembali None, tetapi tidak lagi. Bahkan sebagai atribut kelas atau dalam batas fungsi.
# 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
Karenanya aman untuk mengasumsikan bahwa semua Nonereferensi adalah sama. Tidak ada "kebiasaan" None.
Nonegunakan isoperatorSaat menulis kode, Anda mungkin tergoda untuk menguji Noneness seperti ini:
if value==None:
pass
Atau untuk menguji kepalsuan seperti ini
if not value:
pass
Anda perlu memahami implikasinya dan mengapa itu sering merupakan ide yang baik untuk menjadi eksplisit.
Nonekenapa melakukan ini
value is None
daripada
value==None
Yang pertama setara dengan:
id(value)==id(None)
Padahal ungkapan value==Noneitu sebenarnya diterapkan seperti ini
value.__eq__(None)
jika nilainya benar Nonemaka Anda akan mendapatkan apa yang Anda harapkan.
>>> nothing = function_that_does_nothing()
>>> nothing.__eq__(None)
True
Dalam kebanyakan kasus, hasilnya akan sama, tetapi __eq__()metode ini membuka pintu yang membatalkan jaminan keakuratan, karena dapat ditimpa dalam kelas untuk memberikan perilaku khusus.
Pertimbangkan kelas ini.
>>> class Empty(object):
... def __eq__(self, other):
... return not other
Jadi Anda mencobanya Nonedan berhasil
>>> empty = Empty()
>>> empty==None
True
Tapi kemudian itu juga berfungsi pada string kosong
>>> empty==''
True
Dan lagi
>>> ''==None
False
>>> empty is None
False
Nonesebagai booleanDua tes berikut
if value:
# do something
if not value:
# do something
sebenarnya dievaluasi sebagai
if bool(value):
# do something
if not bool(value):
# do something
Noneadalah "falsey", yang berarti bahwa jika dilemparkan ke boolean ia akan kembali Falsedan jika diterapkan notoperator itu akan kembali True. Namun perlu dicatat bahwa ini bukan properti unik untuk None. Selain itu Falsesendiri, properti dibagi oleh daftar kosong, tupel, set, dikte, string, serta 0, dan semua objek dari kelas yang menerapkan __bool__()metode ajaib untuk kembali False.
>>> 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
Jadi saat menguji variabel dengan cara berikut, waspadalah dengan apa yang Anda sertakan atau tidak termasuk dalam tes:
def some_function(value=None):
if not value:
value = init_value()
Di atas, apakah Anda bermaksud menelepon init_value()saat nilai diatur secara khusus None, atau apakah Anda maksud bahwa nilai ditetapkan 0, atau string kosong, atau daftar kosong juga harus memicu inisialisasi. Seperti yang saya katakan, berhati-hatilah. Seperti yang sering terjadi dalam Python eksplisit lebih baik daripada implisit .
None dalam praktekNone digunakan sebagai nilai sinyalNonememiliki status khusus dalam Python. Ini adalah nilai dasar favorit karena banyak algoritma memperlakukannya sebagai nilai luar biasa. Dalam skenario seperti itu dapat digunakan sebagai tanda untuk memberi sinyal bahwa suatu kondisi memerlukan penanganan khusus (seperti pengaturan nilai default).
Anda dapat menetapkan Noneargumen kata kunci dari suatu fungsi dan kemudian secara eksplisit mengujinya.
def my_function(value, param=None):
if param is None:
# do something outrageous!
Anda dapat mengembalikannya sebagai default ketika mencoba untuk mendapatkan atribut objek dan kemudian secara eksplisit mengujinya sebelum melakukan sesuatu yang istimewa.
value = getattr(some_obj, 'some_attribute', None)
if value is None:
# do something spectacular!
Secara default metode kamus get()kembali Noneketika mencoba mengakses kunci yang tidak ada:
>>> some_dict = {}
>>> value = some_dict.get('foo')
>>> value is None
True
Jika Anda mencoba mengaksesnya dengan menggunakan notasi subskrip, maka KeyErrorakan dimunculkan
>>> value = some_dict['foo']
KeyError: 'foo'
Demikian juga jika Anda mencoba memunculkan item yang tidak ada
>>> value = some_dict.pop('foo')
KeyError: 'foo'
yang dapat Anda tekan dengan nilai default yang biasanya diatur ke None
value = some_dict.pop('foo', None)
if value is None:
# booom!
None digunakan sebagai bendera dan nilai yang validPenggunaan yang dijelaskan di atas Noneberlaku ketika tidak dianggap sebagai nilai yang valid, tetapi lebih seperti sinyal untuk melakukan sesuatu yang istimewa. Namun ada situasi di mana kadang-kadang penting untuk mengetahui dari mana Noneasalnya karena meskipun itu digunakan sebagai sinyal itu juga bisa menjadi bagian dari data.
Saat Anda meminta objek untuk atributnya dengan getattr(some_obj, 'attribute_name', None)membalas Nonetidak memberi tahu Anda apakah atribut yang Anda coba akses diset ke Noneatau jika itu sama sekali tidak ada dari objek. Situasi yang sama ketika mengakses kunci dari kamus seperti some_dict.get('some_key'), Anda tidak tahu apakah some_dict['some_key']ada yang hilang atau hanya diatur ke None. Jika Anda memerlukan informasi itu, cara biasa untuk menangani ini adalah dengan langsung mencoba mengakses atribut atau kunci dari dalam sebuah try/exceptkonstruksi:
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 hanling 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)
Demikian pula dengan dikt:
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)
Dua contoh di atas menunjukkan bagaimana menangani kasus objek dan kamus, bagaimana dengan fungsi? Hal yang sama, tetapi kami menggunakan argumen kata kunci tanda bintang ganda untuk tujuan itu:
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"')
None hanya digunakan sebagai nilai yang validJika Anda menemukan bahwa kode Anda dikotori dengan try/exceptpola di atas hanya untuk membedakan antara Noneflag dan Nonedata, maka gunakan saja nilai tes lain. Ada pola di mana nilai yang berada di luar rangkaian nilai yang valid dimasukkan sebagai bagian dari data dalam struktur data dan digunakan untuk mengontrol dan menguji kondisi khusus (misalnya batas, keadaan, dll). Nilai seperti ini disebut sentinel dan dapat digunakan dengan cara Noneyang digunakan sebagai sinyal. Ini sepele untuk membuat sentinel dengan Python.
undefined = object()
The undefinedobjek di atas adalah unik dan tidak melakukan apa-apa yang mungkin menarik untuk sebuah program, itu sehingga pengganti yang sangat baik untuk Nonesebagai bendera. Beberapa peringatan berlaku, lebih lanjut tentang hal itu setelah kode.
Dengan fungsi
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
Dengan dikt
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
Dengan sebuah benda
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
Seperti yang saya sebutkan sebelumnya penjaga adat datang dengan beberapa peringatan. Pertama, itu bukan kata kunci None, jadi python tidak melindunginya. Anda dapat menimpa undefineddi atas kapan saja, di mana saja dalam modul yang ditentukan, jadi berhati-hatilah bagaimana Anda mengekspos dan menggunakannya. Selanjutnya, instance yang dikembalikan oleh object()bukan singleton, jika Anda melakukan panggilan itu 10 kali Anda mendapatkan 10 objek yang berbeda. Akhirnya, penggunaan sentinel sangat istimewa. Sentinel khusus untuk perpustakaan yang digunakan dan karenanya cakupannya umumnya harus dibatasi untuk internal perpustakaan. Seharusnya tidak "bocor" keluar. Kode eksternal seharusnya hanya menyadarinya, jika tujuannya adalah untuk memperluas atau menambah API perpustakaan.
Ini tidak disebut null seperti dalam bahasa lain, tetapi None. Selalu ada hanya satu instance dari objek ini, sehingga Anda dapat memeriksa kesetaraan dengan x is None(perbandingan identitas), bukan x == None, jika Anda mau.
None. Maka semua orang pintar yang dibandingkan dengan NoneTypeakan menang!
Dalam Python, untuk mewakili tidak adanya nilai, Anda dapat menggunakan nilai None ( types.NoneType.None ) untuk objek dan "" (atau len () == 0 ) untuk string. Karena itu:
if yourObject is None: # if yourObject == None:
...
if yourString == "": # if yourString.len() == 0:
...
Mengenai perbedaan antara "==" dan "adalah", pengujian untuk identitas objek menggunakan "==" harus memadai. Namun, karena operasi "adalah" didefinisikan sebagai operasi identitas objek, mungkin lebih tepat untuk menggunakannya, daripada "==". Tidak yakin apakah ada perbedaan kecepatan.
Bagaimanapun, Anda dapat melihat:
0 == falsekembali trueadalah karena operator double-equals mengetikkan paksaan. Namun, dengan operator triple-equals, 0 === falsepengembalian false, karena 'angka' dan 'boolean' adalah tipe yang berbeda.
truedalam kondisi. Di Rust and Go, 0dan false ada berbagai jenis yang tidak dapat dibandingkan untuk kesetaraan.
Null adalah jenis objek khusus seperti:
>>>type(None)
<class 'NoneType'>
Anda dapat memeriksa apakah suatu objek ada di kelas 'NoneType':
>>>variable = None
>>>variable is None
True
Informasi lebih lanjut tersedia di Python Docs
Pengujian nilai Per Truth , 'None' langsung menguji sebagai FALSE, jadi ungkapan paling sederhana akan cukup:
if not foo:
Trueuntuk setiap nilai falsy, bukan hanya None.
egg is Nonelebihegg == None: Yang terakhir dapat kelebihan beban, dan cenderung rusak ketika membandingkan objek yang valid dengan Tidak Ada (tergantung pada bagaimana itu diterapkan, tetapi Anda tidak mengharapkan semua orang untuk mengambil perbandingan dengan Tidak Ada ke dalam akun, bukan?) , sementaraisselalu bekerja sama.