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: