Barcha qo'llanmalar

Python'da Null (None): yetishmayotgan qiymatlar va NoneType bo'yicha qo'llanma

Python'dagi Null'ni o'rganing: yetishmayotgan qiymatlar bilan ishlashni puxta egallang, identity operator'laridan to'g'ri foydalaning, keng tarqalgan bug'lardan qoching va tozaroq kod uchun best practice'larga amal qiling.

Muallif: Kimberly Fessel

Agar "hech narsa"ga nom bera olsangiz, uni nima deb atagan bo'lardingiz? Ko'plab dasturlash tillari, jumladan SQL, Java va C#, uni "null" deb ataydi. Boshqa tillarda null pointer'lar yoki null reference'larga ham duch kelgan bo'lishingiz mumkin.

Python'da null None deb ataladi. Uni yaratish juda oson, lekin None'ni tekshirish uchun maxsus operator'lar kerak bo'ladi.

Ushbu maqolada o'sha operator'larni, shuningdek, uning keng tarqalgan qo'llanishlari, best practice'lar va "tuzoq"larni ko'rib chiqamiz, shunda nima bo'layotganidan None — ya'ni mutlaqo bexabar qolib ketmaysiz.

Python'da "Null" nima?

An'anaga ko'ra null yetishmayotgan ma'lumotni yoki qiymat yo'qligini ifodalaydi. Null'ni aniq bir qiymatdan ko'ra ko'proq tushuncha sifatida tasavvur qiling. U qiymat yetishmayotganini, mavjud emasligini yoki ataylab berilmaganini bildiradi. Python yetishmayotgan qiymatlarni None keyword'i bilan belgilaydi. Bu falsy Python obyekti, lekin u bo'sh string, nol yoki bo'sh list kabi boshqa falsy qiymatlarga ekvivalent emas. None'ni parametrning sukut bo'yicha qiymati sifatida, funksiyalardan qaytariladigan qiymat sifatida, collection'ga o'xshash ma'lumotlar tuzilmalari ichida va mustaqil holda uchratasiz.

Python'da None: null obyektlarni aniqlash va uning ma'lumot tipi

Python'da None'ni uning built-in keyword'i yordamida o'zgaruvchiga berasiz:

x = None
print(x) 

# Expected result:
# None

None'ni bosh harf bilan yozishni unutmang, chunki Python katta-kichik harflarni farqlaydi. Shuningdek, None NoneType obyekti ekanini ham yodda tuting:

type(x) 

# Expected result:
# <class 'NoneType'>

Bu None'ning type'i NoneType ekanini ko'rsatadi. None obyektini Python siz uchun yaratadi, uni o'zingiz instantiate qilishingiz shart emas.

None — singleton obyekt, ya'ni Python xotirada faqat bitta None obyektini yaratadi. None berilgan har bir o'zgaruvchi o'sha bitta obyektga murojaat qiladi:

a = None
b = None
print(a is b) 

# Expected result:
# True

Biz a va b'ga None beramiz, u esa xotiradagi bitta obyektga ishora qiladi; shuning uchun a is b True qaytaradi.

None'ni tekshirish: is operatori va taqqoslashlar

Python'ning null qiymati kodingizda paydo bo'lgach, keyingi mantiqiy qadam uni tekshirish, ayniqsa conditional'larda. None'ni tekshirishning tavsiya etilgan usuli is identity operatoriga tayanadi:

x = None

if x is None:
    print("x is None")

# Expected result:
# x is None

Xuddi shunday, is not compound operatori teskari tekshiruvni bajarish imkonini beradi:

if x is not None:
    print("x has a value")

Python'da null'ni tekshirishda identity operatori (is) tenglik operatoridan (==) afzal ko'riladi. is operatori obyekt identity'sini tekshiradi, ya'ni ikki o'zgaruvchi xotiradagi aynan bir xil obyektga murojaat qilayotganini aniqlaydi. == None uchun ishlashi mumkin, lekin u custom obyektlarda bir xilda ishlashi kafolatlanmagan. None taqqoslanishi kerak bo'lgan qiymatni emas, balki qiymat yo'qligini ifodalaydi. Shu sababli bizni ekvivalentlik qiziqtirmaydi. Bizni o'zgaruvchi singleton obyekt bo'lgan None'ga ishora qiladimi-yo'qmi, shu qiziqtiradi. is None'dan foydalanish bu niyatni aniq ko'rsatadi va tenglik xatti-harakati moslashtirilgan bo'lishi mumkin bo'lgan har qanday edge case'lardan saqlaydi.

Qoida sifatida: None uchun is / is not'dan foydalaning, =='ni esa qiymatlarni taqqoslash uchun qoldiring.

None'ning eng keng tarqalgan qo'llanishlari

Endi Python'da None'ni qanday yaratish va tekshirishni bilganingizdan so'ng, keling, None odatda paydo bo'ladigan ba'zi joylarni ko'rib chiqamiz.

Funksiya argumentlari uchun sukut bo'yicha parametr sifatida None

None'dan foydalanishning, ehtimol, eng keng tarqalgan usuli — uni funksiya parametrining sukut bo'yicha qiymati sifatida ishlatish. Parametrlar funksiya ta'rifida funksiya nomidan keyin darhol qavs ichida keladi va ularga variable_name = default_value andozasi bo'yicha sukut bo'yicha qiymat berishingiz mumkin. Agar funksiyani chaqirganda ixtiyoriy parametr uchun argument qiymatini bermasangiz, Python sukut bo'yicha qiymatdan foydalanadi.

Quyida foydalanuvchini qutlaydigan funksiya misoli keltirilgan. Agar name uchun funksiya argumenti berilmasa, parametr sukut bo'yicha None bo'ladi va funksiya umumiy salomlashuvni chiqaradi:

def greet(name=None):
    if name is None:
        print("Hi there!")
    else:
        print(f"Hi, {name}!")

greet(name="Sarah")
greet()

# Expected result:
# Hi, Sarah!
# Hi there!

Bo'sh string'ga tayanishdan ko'ra, ixtiyoriy funksiya argumenti uchun sukut bo'yicha qiymat sifatida None'dan foydalanish qiymat berilmagan holatni aniqlash va uni funksiya ichida alohida hal qilish imkonini beradi. Sukut bo'yicha qiymatlarni berish uchun or operatori ishlatilishini ham ko'rasiz, biroq u faqat None'da emas, har qanday falsy qiymatda ishga tushadi.

Sukut bo'yicha qaytariladigan qiymat sifatida None

Har bir Python funksiyasi qiymat qaytaradi, hatto siz buni aniq dasturlamagan bo'lsangiz ham. return statement'i bo'lmagan ushbu oddiy salomlashuv funksiyasining kodini ko'rib chiqing:

def greet_simple():
    print("Hi there!")

output = greet_simple()
print(output)

# Expected result:
# Hi there!
# None

Funksiya salomlashuvni chiqaradi, lekin unda return statement'i yo'q, shuning uchun Python sukut bo'yicha None qaytaradi. Buni output'ning type'i NoneType ekanini tekshirish orqali tasdiqlashingiz mumkin:

print(type(output)) 

# Expected result:
# <class 'NoneType'>

Asosiy maqsadi chop etish, faylga yozish, data visualization yaratish va shu kabi side effect bo'lgan funksiya ko'pincha None qaytaradi. Funksiyada qiymatsiz return statement'i bo'lganda ham Python None qaytaradi. None sukut bo'yicha qaytariladigan qiymat bo'lgani uchun aniq hech narsa qaytarmaydigan funksiyalar bilan ishlaganda unga tez-tez duch kelasiz. Bir nechta qiymat qaytaradigan funksiyalar buni aniq tarzda, ularni tuple yoki boshqa collection'ga joylash orqali amalga oshiradi.

Ma'lumotlar tuzilmalaridagi None qiymatlar

None list'lar va dictionary'lar kabi collection'lar ichida to'g'ri element sifatida ham paydo bo'lishi mumkin, u yerda u ko'pincha yetishmayotgan ma'lumot uchun placeholder vazifasini bajaradi. Masalan, quyidagi list foydalanuvchi nomlari va noma'lum qiymatlar aralashmasidan iborat:

users = ["Sarah", None, "Mike", "Kiki", None]
print(users) 

# Expected result:
# ['Sarah', None, 'Mike', 'Kiki', None]

None'ni dictionary qiymatlari sifatida ham ko'rasiz. (U to'g'ri key ham bo'la oladi, lekin bu kamroq uchraydi.) Bu yerda user'da phone maydoni bor, lekin telefon raqami berilmagan:

user = {
    "name": "Sarah",
    "subscription": "Pro",
    "phone": None
}

print(user["phone"])

# Expected result:
# None

Va nihoyat, linked list'da None zanjirning oxirini belgilaydi: oxirgi node'ning next attribute'i None bo'ladi.

None oddiy Python obyekti bo'lgani uchun uni string'lar, sonlar va boshqa qiymatlar kabi collection'larda saqlashingiz mumkin.

Python'da None va NaN

Agar NumPy yoki pandas olamiga qadam qo'ygan bo'lsangiz, ehtimol "not a number" (son emas) degan ma'noni anglatuvchi NaN'ga duch kelgansiz. None va NaN o'rtasida o'xshashlik izlash juda jozibali, chunki ikkalasi ham "null'ga o'xshash" tuyuladi va yetishmayotgan yoki noma'lum qiymatlar bilan bog'lanadi. Biroq yodda tutish kerak bo'lgan bir nechta muhim farqlar bor.

Xususiyat None NaN
Ta'rifi Qiymat yo'qligi Noto'g'ri/aniqlanmagan sonli qiymat
Type NoneType float
Qo'llanishi Umumiy maqsadli Sonli/tahliliy workflow'lar
Taqqoslash is'dan foydalaning math.isnan()'dan foydalaning

Quyidagi kod Python'da built-in math kutubxonasi orqali NaN'ni namoyish etadi:

x = float('nan')

print(x)
print(type(x))
print(math.isnan(x))

# Expected result:
# nan
# <class 'float'>
# True

Ammo NaN'ning eng katta tuzog'i mana bu:

print(float('nan') == float('nan'))

# Expected result:
# False

None'dan farqli o'laroq, NaN qiymati o'ziga teng hisoblanmaydi, shu sababli uni aniqlash uchun math.isnan() kabi funksiyalar mutlaqo zarur.

Yetishmayotgan qiymatlar bilan ishlash: best practice'lar

Null qiymatlar bilan ishlashdagi best practice'lar haqida butun boshli kitoblar yozilgan, lekin biz qisqa to'xtalamiz. Python'ning null qiymati — None bilan ishlash ko'nikmalaringiz oshgani sari kodingizni yuqori darajaga olib chiqishning ba'zi usullari quyida keltirilgan.

Type hint'larda None

C va Java kabi boshqa dasturlash tillaridan farqli o'laroq, Python o'zgaruvchilarini dinamik tiplaydi, ya'ni yaratgan har bir o'zgaruvchingiz turini e'lon qilishingiz shart emas. Bu kod yozish tezligini oshiradi, lekin keyinchalik, ayniqsa foydalanuvchi tomonidan aniqlangan Python funksiyalarida yoki environment variable'larni sozlashda chalkashlikka olib kelishi mumkin (masalan, environment variable o'rnatilmagan bo'lsa, os.getenv() None qaytaradi)

Python 3.5'da (2015) joriy etilgan type hinting o'qilishni va debugging'ni yaxshilaydi. Funksiyaning kutilayotgan kirish va chiqish type'larini belgilash uchun type hint'lardan foydalanishingiz mumkin. Masalan, quyidagi salomlashuv funksiyasi string bo'lgan bitta kirish qiymati — name'ni kutadi va None qaytaradi:

def greet_string(name: str) -> None:
    print(f"Hi, {name}!")

greet_string("Sarah")

# Expected result:
# Hi, Sarah!

Avval ko'rsatilganidek, None ko'pincha sukut bo'yicha qiymat vazifasini bajaradi:

def greet(name=None):
    if name is None:
        print("Hi there!")
    else:
        print(f"Hi, {name}!")

greet()

# Expected result:
# Hi there!

Ammo bu type hinting uchun nimani anglatadi? Ma'lum bo'lishicha, bu type'larni pipe belgisi bilan birlashtirib, Python'ga name parametri uchun string yoki None kutishni aytishingiz mumkin:

def greet(name: str | None = None) -> None:
    if name is None:
        print("Hi there!")
    else:
        print(f"Hi, {name}!")

greet()

# Expected result:
# Hi there!

Type hint'lar None tasodifiy kirish qiymati emas, balki kutilgan qiymat ekanini aniq ko'rsatib, o'qilishni yaxshilaydi. Shuningdek, type hinting uchun bu sintaksis (str | None) Python 3.10'da (2021) joriy etilgan, shuning uchun legacy tizimlarda buning o'rniga typing kutubxonasidan import qilingan va Optional[str] ko'rinishida qo'llanilgan Optional'ni ko'rishingiz mumkin.

Erta himoyalaning, ichma-ich joylashtirmang

None sukut bo'yicha funksiya parametri sifatida ayniqsa foydali ekanini ko'rasiz, lekin ko'plab talablarga ega conditional'larni haddan tashqari ichma-ich joylashtirib yubormaslikka ehtiyot bo'ling. Chuqur ichma-ich joylashgan mantiqni o'qish ancha qiyin. Masalan, aytaylik, hashamatli mahsulotlarni asl narxning 90 foizigacha chegirma qilmoqchisiz. Buni bajaradigan ichma-ich tuzilgan Python funksiyasi mana bunday:

def apply_discount(price, category=None):
    if price is not None:
        if category == "luxury":
            return price * 0.9
        return price
    return None

print(apply_discount(100, category="luxury"))

# Expected result:
# 90.0

Bu funksiya o'z vazifasini bajarsa-da, aslida qaysi mahsulotlar chegirma olishini tezda tushunish qiyin.

Ichma-ich joylashtirish o'rniga, maxsus holatlarni erta hal qilish uchun funksiyani guard clause'lar yordamida qayta yozing:

def apply_discount(price, category=None):
    if price is None:
        return None

    if category == "luxury":
        return price * 0.9

    return price

print(apply_discount(100, category="luxury"))

# Expected result:
# 90.0

Guard clause'lar None bilan ishlashni funksiyaning yuqori qismida saqlaydi, shunda qolgan mantiq faqat ma'noli, to'g'ri qiymatlar bilan ishlaydi — bu o'qilishni yaxshilaydi va bug'larni kamaytiradi.

Keng tarqalgan bug'lar va ulardan qanday qochish mumkin

Python'da null bo'yicha best practice'larga amal qilishga harakat qilsangiz ham, ertami-kechmi bug'lar paydo bo'lishi muqarrar. Eng keng tarqalganlari va ulardan qanday qochish mumkinligini bilish uchun o'qishda davom eting.

return statement'ini unutish

Avval ko'rganingizdek, Python funksiyalari har doim nimadir qaytaradi va qaytariladigan qiymat ko'rsatilmagan bo'lsa, sukut bo'yicha None qaytaradi. Agar return statement'ini qo'shishni unutsangiz, funksiyangiz tasodifan None qaytarishi mumkin:

def multiply(a, b):
    result = a * b 

product = multiply(2, 3)
print(product)

# Expected result:
# None

Bu holatda funksiya hisoblashni bajaradi, lekin natijani qaytarmaydi, shuning uchun Python yashirin tarzda None qaytaradi.

Bu yangi boshlovchilarning eng keng tarqalgan xatolaridan biri va agar funksiya natijasi keyingi hisob-kitoblarga uzatilsa, keyinchalik muammolarga sabab bo'lishi mumkin. Qiymat qaytarishi kerak bo'lgan funksiyalarda return statement'i aniq yozilganiga ishonch hosil qilib, bu tuzoqdan qoching va funksiya natijalarini keyingi mantiqda ishlatishdan oldin har doim testlang.

None ustida zanjirli method chaqiruvlari (AttributeError)

Python obyektlari ko'pincha method chaining'ni qo'llab-quvvatlaydi, bunda bitta method chaqiruvining natijasi darhol keyingisi tomonidan ishlatiladi:

name = " Sarah  "
print(name.strip().upper())

# Expected result:
# SARAH

Muammo shundaki, string'lar, list'lar yoki foydalanuvchi tomonidan aniqlangan obyektlardan farqli o'laroq, None'da hech qanday method yoki attribute yo'q. Agar uning ustida method'larni zanjir qilib chaqirishga urinsangiz, xatoga duch kelasiz. Quyidagi funksiya foydalanuvchini ID bo'yicha qidiradi. ID'si 3 bo'lgan foydalanuvchi mavjud bo'lmagani uchun dictionary'dan qidirish None qaytaradi. So'ng siz o'sha None qiymati ustida .upper()'ni chaqirishga uringaningizda Python AttributeError chiqaradi:

def find_user(user_id):
    users = {
        1: "Sarah",
        2: "Mike"
    }
    return users.get(user_id)

print(find_user(3).upper())

# Expected result:
# AttributeError: 'NoneType' object has no attribute 'upper'

Agar Python'da qiymat None bo'lsa, uning ustidagi har qanday zanjirli method chaqiruvlari darhol AttributeError bilan muvaffaqiyatsiz tugaydi. Qiymat ustida qo'shimcha amallarni bajarishdan oldin har doim None'ni tekshiring.

Xulosa

Agar Python'da null qiymat izlayotgan bo'lsangiz, u — None. Bu maxsus singleton obyekt qiymat yo'qligini ifodalaydi va ko'pincha sukut bo'yicha qaytariladigan qiymat yoki funksiya argumenti uchun parametr sifatida uchraydi. Uni tekshirish uchun is None yoki is not None'dan foydalaning va NaN, ya'ni "not a number", ham yetishmayotgan ma'lumotlar bilan bog'langan bo'lsa-da, boshqa maqsadga xizmat qilishini yodda tuting.

None bilan ishlaganda guard clause'larni erta qo'shing, o'rinli joylarda type hint'lardan foydalaning va return statement'ini tushirib qoldirib, tasodifan None qaytarib qo'ymaslikka ehtiyot bo'ling.

Eslab qolish kerak bo'lgan None maslahatlari ko'pmi? Bo'lmasam-chi. Yangi olgan bilimlaringizni mustahkamlash uchun AI Tutor bilan biroz vaqt ishlab ko'ring:

Yo'l xaritalariQo'llanmalarFAQYouTube

yo'lxaritaroadmap.shasosida

Hamjamiyat tomonidan yaratilgan yo'l xaritalari, eng yaxshi amaliyotlar, loyihalar, maqolalar, manbalar va yo'nalishlar — o'z yo'lingizni tanlash va kasbingizda o'sish uchun.

© yo'lxarita·Shartlar·Maxfiylik·

roadmap.sh

Barcha kontent roadmap.sh loyihasidan olingan (© Kamran Ahmed) va shaxsiy o'rganish uchun o'zbek tiliga tarjima qilinmoqda.

Qidiruv

Yo'l xaritalari, loyihalar va savollarni qidiring