null objek di Python?

Bagaimana saya merujuk ke objek null dalam Python?

Larutan

Di Python, yang 'null' obyek singleton None.

Cara terbaik untuk memeriksa hal-hal untuk "Noneness" adalah dengan menggunakan identitas operator, adalah:

if foo is None:
    ...
Komentar (10)

None, Python's null?

Ada's tidak ada null di Python, malah ada's Tidak ada. Seperti yang dinyatakan sudah cara yang paling akurat untuk menguji bahwa sesuatu yang telah diberikan None sebagai nilai adalah dengan menggunakan adalah identitas operator, yang menguji bahwa dua variabel yang mengacu pada objek yang sama.

>>> foo is None
True
>>> foo = 'bar' 
>>> foo is None
False

Dasar #

Ada dan hanya bisa menjadi salah satu None ##

None adalah satu-satunya contoh dari kelas NoneType dan setiap upaya lebih lanjut di instantiate kelas itu akan kembali objek yang sama, yang membuat None tunggal. Pendatang baru ke Python sering melihat pesan kesalahan yang menyebutkan NoneType dan bertanya-tanya apa itu. It's pendapat pribadi saya bahwa pesan-pesan ini hanya bisa hanya menyebutkan Tidak dengan nama karena, seperti yang kita'll melihat sesaat, None meninggalkan sedikit ruang untuk ambiguitas. Jadi, jika anda melihat beberapa TypeError pesan yang menyebutkan bahwa NoneType dapat't melakukan ini atau dapat't melakukan itu, hanya tahu bahwa itu's hanya satu Tidak ada yang digunakan dalam cara yang dapat't. Juga, None adalah built-in konstan, segera setelah anda mulai Python itu's yang tersedia untuk digunakan dari mana saja, baik di dalam modul, kelas, atau fungsi. NoneType dengan kontras tidak, anda'a perlu untuk mendapatkan referensi untuk itu pertama dengan query Tidak untuk kelasnya.

>>> NoneType
NameError: name 'NoneType' is not defined
>>> type(None)
NoneType

Anda dapat memeriksa None's keunikan dengan Python's identitas fungsi id(). Ia mengembalikan nomor unik yang diberikan kepada suatu objek, masing-masing objek memiliki satu. Jika id dari dua variabel adalah sama, maka mereka menunjuk pada fakta untuk 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

Tidak ada tidak akan ditimpa

Dalam banyak versi Python (sebelum 2.4) adalah mungkin untuk menetapkan kembali Tidak, tapi sekarang tidak lagi. Bahkan bukan sebagai atribut class atau dalam batas-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

It's oleh karena itu aman untuk mengasumsikan bahwa semua None referensi yang sama. Ada's tidak ada "kustom" Tidak ada.

Untuk menguji untuk Tidak gunakan adalah operator

Saat 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 implikasi dan mengapa hal itu's sering ide yang baik untuk menjadi eksplisit.

Kasus 1: pengujian jika nilai None

mengapa ini

value is None

daripada

value==None

Yang pertama adalah setara dengan:

id(value)==id(None)

Sedangkan ungkapan value==None ini sebenarnya diterapkan seperti ini

value.__eq__(None)

jika nilai benar-benar adalah Tidak maka anda'll mendapatkan apa yang anda harapkan.

>>> nothing = function_that_does_nothing()
>>> nothing.__eq__(None)
True

Dalam kebanyakan kasus umum hasilnya akan sama, tapi __eq__() metode terbuka sebuah pintu yang void jaminan akurasi, karena itu dapat diganti dalam kelas untuk memberikan perilaku khusus. Pertimbangkan kelas ini.

>>> class Empty(object):
...     def __eq__(self, other):
...         return not other

Jadi anda mencobanya pada None dan bekerja

>>> empty = Empty()
>>> empty==None
True

Tapi kemudian ia juga bekerja pada string kosong

>>> empty==''
True

Namun

>>> ''==None
False
>>> empty is None
False

Kasus 2: Menggunakan None sebagai boolean

Berikut dua tes

if value:
    # do something

if not value:
    # do something

sebenarnya dievaluasi sebagai

if bool(value):
    # do something

if not bool(value):
    # do something

None adalah "falsey", yang berarti bahwa jika dilemparkan ke boolean itu akan kembali Palsu dan jika diterapkan dengan tidak operator ini akan mengembalikan True. Namun, perlu diingat bahwa itu's tidak properti unik untuk Tidak ada. Selain Palsu itu sendiri, properti yang dimiliki oleh kosong list, tuple, set, dicts, string, serta 0, dan semua objek dari kelas yang menerapkan __bool__() metode magic untuk kembali Palsu.

>>> 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, ketika pengujian untuk variabel dengan cara berikut, harus ekstra menyadari apa yang anda're termasuk atau tidak termasuk dari test:

def some_function(value=None):
    if not value:
        value = init_value()

Di atas, apakah yang anda maksud untuk memanggil init_value() ketika nilai yang ditetapkan secara khusus untuk Tidak ada, atau apakah anda berarti bahwa nilai yang ditetapkan ke 0, atau string kosong, atau daftar kosong juga harus memicu inisialisasi. Seperti yang aku bilang, berhati-hati. Sebagai it's sering terjadi di Python eksplisit lebih baik dari implisit.

None dalam praktek #

Tidak ada yang digunakan sebagai nilai sinyal

Tidak memiliki status khusus di Python. It's favorit dasar nilai karena banyak algoritma memperlakukannya sebagai nilai yang luar biasa. Dalam skenario seperti itu dapat digunakan sebagai bendera untuk menandakan bahwa suatu kondisi yang memerlukan penanganan khusus (seperti pengaturan nilai default). Anda dapat menetapkan Tidak untuk kata kunci argumen dari fungsi dan kemudian secara eksplisit tes untuk itu.

def my_function(value, param=None):
    if param is None:
        # do something outrageous!

Anda dapat mengembalikannya sebagai default ketika mencoba untuk mendapatkan ke objek's atribut dan kemudian secara eksplisit tes untuk itu sebelum melakukan sesuatu yang khusus.

value = getattr(some_obj, 'some_attribute', None)
if value is None:
    # do something spectacular!

Secara default kamus's get() mengembalikan Tidak ketika mencoba untuk mengakses non-kunci yang ada:

>>> some_dict = {}
>>> value = some_dict.get('foo')
>>> value is None
True

Jika anda mencoba untuk mengaksesnya dengan menggunakan subscript notasi yang KeyError akan dinaikkan

>>> value = some_dict['foo']
KeyError: 'foo'

Demikian juga jika anda mencoba untuk pop non-item ada

>>> value = some_dict.pop('foo')
KeyError: 'foo'

yang dapat anda menekan 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 berlaku

Yang dijelaskan di atas menggunakan Tidak berlaku saat itu tidak dianggap nilai yang berlaku, tetapi lebih seperti sebuah sinyal untuk melakukan sesuatu yang khusus. Ada situasi namun di mana ia kadang-kadang penting untuk tahu di mana None datang dari karena meskipun itu's digunakan sebagai sinyal ini juga bisa menjadi bagian dari data. Ketika anda meminta objek untuk atribut dengan getattr(some_obj, 'attribute_name', Tidak ada) kembali None doesn't memberitahu anda jika atribut yang ingin anda akses ditetapkan untuk Tidak ada atau jika itu sama sekali absen dari objek. Situasi yang sama ketika mengakses sebuah kunci dari kamus seperti some_dict.mendapatkan('some_key'), anda don't tahu jika some_dict['some_key'] hilang atau jika itu's hanya mengatur ke None. Jika anda membutuhkan informasi itu, cara yang biasa untuk menangani ini adalah untuk langsung mencoba mengakses atribut atau kunci dari hanya mencoba/kecuali membangun:

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

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)

Di atas dua contoh yang menunjukkan bagaimana untuk menangani objek dan kamus kasus, apa tentang fungsi? Hal yang sama, tapi kita menggunakan tanda bintang ganda kata kunci argumen untuk 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 berlaku

Jika anda menemukan bahwa kode anda dipenuhi dengan hal tersebut di atas mencoba/kecuali pola hanya untuk membedakan antara None bendera Tidak ada data, maka hanya menggunakan tes lain nilai. Ada's sebuah pola di mana nilai yang berada di luar himpunan nilai yang berlaku dimasukkan sebagai bagian dari data dalam struktur data dan digunakan untuk kontrol dan tes kondisi khusus (misalnya batas wilayah, negara, dll). Nilai tersebut disebut sentinel dan hal ini dapat digunakan dengan cara yang Tidak ada yang digunakan sebagai sinyal. It's sepele untuk menciptakan sentinel di Python.

undefined = object()

The undefined objek di atas adalah unik dan doesn't melakukan apa-apa yang mungkin menarik untuk sebuah program,'s jadi pengganti yang sangat baik untuk Tidak ada sebagai bendera. Beberapa peringatan berlaku, lebih banyak tentang 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 dict

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 objek

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 kustom penjaga datang dengan beberapa peringatan. Pertama, mereka're tidak kata kunci seperti Tidak, sehingga python doesn't melindungi mereka. Anda dapat menimpa anda undefined di atas setiap saat, di mana saja di modul itu's didefinisikan, jadi hati-hati bagaimana anda mengekspos dan menggunakan mereka. Berikutnya, contoh dikembalikan oleh objek() adalah tidak tunggal, jika anda membuat panggilan 10 kali anda mendapatkan 10 objek yang berbeda. Akhirnya, penggunaan sentinel adalah sangat istimewa. Sentinel adalah khusus untuk perpustakaan itu's digunakan dalam dan ruang lingkup umumnya harus terbatas ke perpustakaan's internal. Seharusnya't "bocoran" out. Eksternal kode hanya harus menyadari hal itu, jika tujuan mereka adalah untuk memperluas atau menambah perpustakaan's API.

Komentar (5)

It's tidak disebut null seperti dalam bahasa-bahasa lain, tetapi None. Selalu ada hanya satu contoh dari objek ini, sehingga anda dapat memeriksa untuk kesetaraan dengan x Ada (identitas perbandingan) dan bukan x == None, jika anda ingin.

Komentar (1)

Di Python, untuk mewakili tidak adanya nilai, anda dapat menggunakan Tidak ada nilai (jenis.NoneType.Tidak ada) untuk benda-benda dan "" (atau len() == 0) untuk string. Oleh karena itu:

if yourObject is None:  # if yourObject == None:
    ...

if yourString == "":  # if yourString.len() == 0:
    ...

Mengenai perbedaan antara "==" dan "adalah", pengujian mengenai identitas objek menggunakan "==" harus cukup. Namun, sejak operasi "adalah" didefinisikan sebagai identitas objek operasi, hal ini mungkin lebih tepat untuk menggunakannya, bukan "==". Tidak yakin bahkan jika ada perbedaan kecepatan.

Lagi pula, anda bisa melihat-lihat di:

Komentar (7)

Per Kebenaran nilai pengujian, 'Ada' langsung tes sebagai PALSU, sehingga ekspresi yang paling sederhana akan cukup:

if not foo:
Komentar (2)