Ачааллж байна...
Энэ бол олон бүлгийн турш амлагдсаар ирсэн хичээл. Тоолж үзье: input()-ын хичээлд "хэрэглэгч 'арван хоёр' гэж бичихэд гардаг ValueError бол таны кодын буруу биш — хамгаалалтыг нь Бүлэг 11-д хийнэ" гэж; тоон үйлдлүүдийн хичээлд "тэг хуваарийн аюулгүйн тор Бүлэг 11-д бий" гэж; өмнөх лавлах хичээлд ValueError-ын жор дээр "хамгаалалт нь дараагийн хичээлийн try/except" гэж — гурван том өр. Өнөөдөр бүгдийг барагдуулна. Асуудлын мөн чанарыг нэг өгүүлбэрт багтаавал: зарим алдаа таны кодоос биш — гадаад ертөнцөөс ирдэг. Кодын алдааг (үсгийн алдаа, мартагдсан хоёр цэг...) та засаад арилгачихна — харин "хэрэглэгч тоо асуухад үсэг бичих" гэдгийг засах арга байхгүй: хэрэглэгч бол таны кодын гадна орших, урьдчилан таамаглашгүй ертөнц. Тэгэхээр асуулт өөрчлөгдөнө: "алдаа гаргахгүй яаж бичих вэ" биш — "алдаа гарахад программ маань унахгүй яаж байх вэ": энэ асуултын хариулт нь try / except — Python-ы аюулгүйн тор.
Нэрсийг нь эхэлж тайлъя: try — "оролдоод үз", except — "гэхдээ хэрэв (алдаа гарвал)". Хоёул Python-ы нөөцөлсөн үгс, хоёул таны сайн таньдаг хэлбэрээр амьдардаг: хоёр цэг + шигдсэн бие — if/else хосын "алдааны ертөнц дэх төрөл садан" гэж бодоход ойрхон. Гэхдээ энэ хичээлийн төгсгөлд бид нэг шударга яриа өрнүүлнэ: try/except бол хүчирхэг тор боловч бүх кодоо тороор ороох нь эхлэгчдийн хамгийн хортой зуршлуудын нэг — хаана хэрэглэх, хаана хэрэглэхгүй байх хоёулаа өнөөдрийн хичээл.
Try/except-ийг циркийн агаарын гимнастикчийн аюулгүйн тороор төсөөл. Гимнастикч өндөрт үсрэлт хийнэ — ихэнхдээ амжилттай: тор огт ашиглагдахгүй, тоглолт хэвийн үргэлжилнэ. Гэхдээ мянганы нэгэнд гар алдвал — тор барьж авна: унасан ч осол болохгүй, гимнастикч босоод тоглолтоо үргэлжлүүлнэ. Энэ зурагт try/except-ийн бүх механик бий. Try-ийн бие бол үсрэлт — "унаж болзошгүй" гэж таны сэжиглэж буй мөрүүд. Except-ийн бие бол тор — унасан тохиолдолд л ажиллах мөрүүд: амжилттай үсрэлтэд тор юу ч хийдэггүй шиг, алдаагүй гүйлтэд except-ийн бие бүхэлдээ алгасагдана. Хамгийн чухал гурав дахь ажиглалт: тор тодорхой газарт татагддаг — гимнастикчийн доор: циркийн танхимыг бүхэлд нь тороор дүүргэдэггүй. Тор бол "аюултай хэсгийн" хэрэгсэл — энэ ажиглалт хичээлийн төгсгөлийн шударга ярианы үндэс болно. Бас нэг зүйл: тор ослыг арилгадаггүй — унасан нь унасан хэвээрээ: тор зөвхөн уналтыг сүйрэл болгохгүй барьж аваад, "дараа нь юу хийхийг" (босоод дахин үсрэх үү, тайзнаас гарах уу) шийдэх боломж олгодог.
Хамгийн том өрөө эхэлж барагдуулъя — int(input(...))-ын хамгаалалт:
python
try:
nas = int(input("Та хэдэн настай вэ? "))
print(f"Ирэх жил та {nas + 1} настай болно")
except ValueError:
print("Уучлаарай, тоо оруулна уу — жишээ нь: 12")Хоёр гүйлтийг зэрэгцүүлье. Хэрэглэгч 12 гэж бичвэл:
Та хэдэн настай вэ? 12
Ирэх жил та 13 настай болноХэрэглэгч арван хоёр гэж бичвэл:
Та хэдэн настай вэ? арван хоёр
Уучлаарай, тоо оруулна уу — жишээ нь: 12Улаан бичиг алга! Өмнө нь энэ орц traceback дэлбэлж программыг унагадаг байсан — одоо эелдэг мэдэгдэл гараад программ амьд үлдлээ. Бүтцийг задалъя. try: — "одоо аюултай хэсэг эхэлж байна, торны дор ажилла": ард нь шууд хоёр цэг (else шиг — нөхцөлгүй), доор нь шигдсэн бие. except ValueError: — "хэрэв ValueError гарвал — энд ир": except нь try-тайгаа нэг түвшинд (if-else хос шиг — эн тэнцүү хамтрагчид), ард нь барих алдааныхаа нэр, тэгээд хоёр цэг, шигдсэн бие. Ажиллагааны хоёр зам: сайн орцод — try-ийн бие эхнээсээ дуустал хэвийн биелж, except бүхэлдээ алгасагдана (тор ашиглагдсангүй); муу орцод — int() дотор ValueError "төрмөгц" try-ийн биеийн биелэлт тэр дор нь тасарч (доорх f-string мөр огт ажиллаагүйг ажигла — хагас насны мэдээлэл хэвлэгдээгүй нь зөв!), Python "энэ алдааг барих тор байна уу" гэж хараад — except ValueError торыг олж, биеийг нь биелүүлээд, программ цааш үргэлжилнэ. Except-ийн ард алдааны нэрийг заавал бичдэг гэдгийг одооноос дүрэм болгоё — яагаад гэдэг нь төгсгөлийн ярианы гол сэдэв.
Хоёр дахь жишээ: while-тай хоршил — "зөв орц иртэл асуу". Дээрх хувилбар муу орцод эелдэг хэлээд л өнгөрч байна — гэтэл ихэнхдээ бидэнд хариулт нь хэрэгтэй: зөв орц иртэл дахин асуумаар байна. Тор + мөнхийн давталт + break — гурван танил гурвалсан хүч:
python
while True:
try:
nas = int(input("Та хэдэн настай вэ? "))
break
except ValueError:
print("Тоо оруулна уу — дахин оролдоорой")
print(f"Баярлалаа! Таны нас: {nas}")арван хоёр, 12г, тэгээд 12 гэж дараалан бичвэл:
Та хэдэн настай вэ? арван хоёр
Тоо оруулна уу — дахин оролдоорой
Та хэдэн настай вэ? 12г
Тоо оруулна уу — дахин оролдоорой
Та хэдэн настай вэ? 12
Баярлалаа! Таны нас: 12Мөшгье: муу орц → int() унав → тор барив → мэдэгдэл → while True эргүүлэв → дахин асуулт... зөв орц ирмэгц → int() амжилттай → break — давталтаас гарав (break нь try-ийн биед байж болно: тэр давталтаас гаргадаг, торонд саадгүй). Энэ найман мөр бол Python эхлэгчдийн замын хамгийн үнэ цэнтэй "жоруудын" нэг: "тоон орцыг найдвартай авах" стандарт хэв маяг — цээжлэх биш ойлгоод хэрэглэдэг байгаарай: таны цаашдын бараг бүх хэрэглэгчтэй программ энэ хэв маягийг ашиглана (тоо таах тоглоомоо энэ ториор хатуужуулах санаа аяндаа төрж байгаа биз — туршилтын хэсэгт!).
Гурав дахь жишээ: хоёр дахь өр — тэг хуваарь. ZeroDivisionError-ын тор:
python
try:
niit_une = int(input("Нийт үнэ: "))
hun = int(input("Хэдэн хүн хуваах вэ? "))
print(f"Хүн бүрд: {niit_une / hun} төгрөг")
except ValueError:
print("Тоо л оруулаарай")
except ZeroDivisionError:
print("Тэг хүнд хуваах аргагүй шүү дээ")Шинэ зүйл: хоёр тор зэрэгцэж байна — нэг try-д хэдэн ч except залгаж болно: гарсан алдааны төрлөөр нь тохирох тор барина: үсэг бичвэл эхний тор (ValueError), 0 гэж хариулбал хуваалт дээр хоёр дахь нь (ZeroDivisionError) — elif-ийн "олон салаа" санааны торон-хувилбар. Тор бүр өөрийн алдаандаа өөрийн хариултай байгаа нь чухал: "Тоо л оруулаарай" ба "Тэг хүнд хуваах аргагүй" — хоёр өөр асуудалд хоёр өөр, оновчтой тусламж: хэрэглэгч юугаа буруу хийснээ ойлгоно. Ерөнхий нэг "бүх алдааны" тортой харьцуулахад энэ ялгаа яагаад амин чухал болохыг төгсгөлийн ярианд.
Дөрөв дэх жишээ: тор function дотор — тэсвэртэй багаж. Тороо function-д хийвэл "унадаггүй багаж" гарна:
python
def too_asuuh(asuult):
while True:
try:
return int(input(asuult))
except ValueError:
print("Тоо оруулна уу!")
nas = too_asuuh("Та хэдэн настай вэ? ")
jin = too_asuuh("Жин (кг): ")
print(f"Нас: {nas}, жин: {jin}")Хоёр дахь жишээний "үнэ цэнтэй жор" маань function болж дахин ашиглагдахуйц боллоо: хоёр асуулт — хоёр дуудлага, тор нэг л газар бичигдсэн (DRY!). Нэг гоё нюанс: break-ийн оронд return ажиллаж байна — зөв орц ирмэгц int()-ийн үр дүн шууд гардуулагдаж, return-ий "гарц" чанар (Бүлэг 8) давталтыг ч, function-ийг ч нэг дор төгсгөнө: break + тусдаа return хоёр мөр байх байсныг нэг мөр болгожээ. Энэ function-ийг өөрийн "хэрэгслийн сан"-д авч үлдээрэй — харилцагчийн дэвтэр, тоо таах тоглоом... таны бүх ирээдүйн программд шууд зөөгөөд хэрэглэж болно.
Хүсвэл туршаад үзээрэй: тоо таах тоглоомынхоо taamag = int(input(...)) мөрийг хоёр дахь жишээний ториор хатуужуулаарай — одоо тоглогч санамсаргүй үсэг дарахад тоглоом унахгүй болно: өөрийн барьсан зүйлээ шинэ мэдлэгээр сайжруулах гурав дахь баяр. Сонирхвол гурав дахь жишээн дээр хоёр торны дарааллыг сольж туршаад — ажиллагаа өөрчлөгдөхгүйг ажигла (торнууд төрлөөрөө таардаг тул elif-ээс ялгаатай нь дараалал нь энд ач холбогдолгүй — гарсан алдаа нэг л төрөлтэй байдаг учраас).
Алдаа 1: Нүцгэн except — бүх алдааг залгидаг тор. Одоо амласан шударга яриа — өнөөдрийн хамгийн чухал хэсэг:
python
try:
nas = int(input("Нас: "))
print(f"Ирэх жил: {nass + 1}")
except:
print("Тоо оруулна уу")except-ийн ард алдааны нэр алга — ийм "нүцгэн" тор бүх төрлийн алдааг барьдаг. Аюулыг нь харцгаая: хэрэглэгч 12 гэж зөв бичлээ — гэтэл "Тоо оруулна уу" гарч байна?! Учир нь хоёр дахь мөрөнд nass гэсэн үсгийн алдаа бий (таны кодын жинхэнэ NameError!) — нүцгэн тор түүнийг ч барьж аваад "хэрэглэгчийн буруу" мэт мэдэгдэл гаргажээ: таны алдааг таниас нуучихлаа. Traceback гарсан бол line, nass, Did you mean — гурван секундын засвар байсныг тор "залгиад" олон цагийн эргэлзээ болгов. Энэ бол өмнөх хичээлүүдийн бүх сургамжийг урвуулж буй хэрэг: бид traceback уншиж сурсан — нүцгэн тор traceback-ийг устгадаг. Төмөр дүрэм: except-ийн ард үргэлж тодорхой нэр (ValueError, ZeroDivisionError...) — "аль алдааг нь хүлээж байгаагаа" нэрлэж чадахгүй байвал энэ нь тор татах биш кодоо ойлгох цаг болсны дохио. (Тэгвэл алдааны нэрийг нь яаж мэдэх вэ? Хамгаалалтгүйгээр нэг зориуд унагаж, traceback-ийн сүүлчийн мөрөөс нэрийг нь ав — мөрдөгчийн чадвар чинь тор татагчийн чадварын суурь нь юм.)
Алдаа 2: Бүх кодоо тортой ороох. Хоёр дахь хортой зуршил — торны "хэтрүүлэлт":
python
try:
ner = input("Нэр: ")
nas = int(input("Нас: "))
und = 120000
niit = und * 12
print(f"{ner}: жилд {niit}")
except ValueError:
print("Алдаа гарлаа")Таван мөр торонд — гэтэл унаж болзошгүй нь ганцхан: int()-ийн мөр. Юу нь муу вэ: нэгд, алдаа гарахад "аль мөр нь" гэдэг мэдээлэл бүдгэрнэ (тор дотор таван сэжигтэн); хоёрд, "Алдаа гарлаа" гэсэн ерөнхий хариулт хэрэглэгчид юу ч хэлэхгүй (гурав дахь жишээний "оновчтой хоёр хариултын" эсрэг зураг); гуравт — хамгийн гүн нь — код "энэ бүхэн аюултай" гэсэн худал мэдрэмж төрүүлнэ: уншигч аль нь жинхэнэ эмзэг цэг болохыг ялгахаа болино. Циркийн дүрмээ сана: тор гимнастикчийн доор — танхим даяар биш: try-ийн биед зөвхөн унаж болзошгүй мөр(үүд) + тэдгээрээс шууд хамаардаг үргэлжлэл нь; бусад нь торны гадна. Хэмжүүр нь энгийн: try-ийн бие аль болох богино — ихэнхдээ нэг-хоёр мөр.
Алдаа 3: Торыг кодын алдаанд хэрэглэх. Гурав дахь, хамгийн зальтай зуршил — "улаан бичиг гарахаар нь try-гээр ороочихдог" рефлекс:
python
try:
print(jagsaalt[5])
except IndexError:
print("Олдсонгүй")Хэрэв jagsaalt үргэлж гурван гишүүнтэй байдаг бол [5] гэдэг нь таны кодын алдаа — засах ёстой зүйл: тор татаад "Олдсонгүй" гэх нь эвдэрсэн шүдээ эмчлүүлэхийн оронд өвдөлт намдаагч ууж явахтай адил — өвдөлт "алга" боловч шүд эвдэрсээр. Хоёр ертөнцийг зааглах асуулт: "энэ алдааг би засаж чадах уу?" Кодын алдаа (үсгийн алдаа, буруу индекс, мартагдсан int()) — засна, тор татахгүй; гадаад ертөнцийн алдаа (хэрэглэгчийн орц, хожим үзэх файлын байхгүй байдал, сүлжээний тасалдал) — засаж чадахгүй, тор татна. Try/except бол "алдаанаас нуугдах" хэрэгсэл биш — "урьдчилан таамаглашгүйтэй мэндлэх" хэрэгсэл: энэ ялгааг барьж чадвал та торыг мэргэжлийн түвшинд хэрэглэж байна гэсэн үг.
try/except бол аюулгүйн тор: try-ийн биед унаж болзошгүй мөрүүд — алдаагүй бол except алгасагдана; алдаа гармагц try-ийн үлдсэн хэсэг тасарч, төрөл таарсан торны бие ажиллаад программ амьд үргэлжилнэ.
Стандарт жор: while True + try + break (эсвэл return) = "зөв орц иртэл асуудаг" тэсвэртэй орц — function болгож хэрэгслийн сандаа ав.
Нэг try-д олон except — алдааны төрөл бүрд өөрийн оновчтой хариулт; except-ийн ард үргэлж тодорхой нэр: нүцгэн тор таны өөрийн алдааг таниас нуудаг.
Тор гимнастикчийн доор — танхим даяар биш: try-ийн бие аль болох богино; "энэ алдааг би засаж чадах уу?" — чадвал зас (кодын алдаа), чадахгүй бол тор тат (гадаад ертөнц).
Гурван өр барагдав: муу орцын ValueError, тэг хуваарийн ZeroDivisionError одоо тортой; тоо таах тоглоом чинь "унадаггүй" болох боломжтой боллоо.
Ингээд "Алдаатай найзлах" бүлэг өндөрлөлөө — та traceback уншдаг, зургаан алдааг монголоор "ярьдаг", тор татдаг боллоо: алдаа таны дайснаас мэдээллийн эх үүсвэр, дараа нь удирдаж болдог үзэгдэл болтлоо хувирлаа. Дараагийн бүлэг Түвшин 3-ын хоёр дахь том бэлгийг авчирна: файлтай ажиллах — программ чинь анх удаа "мартдаггүй" болно: бичсэнээ файлд хадгалж, дараагийн гүйлтдээ эргэж уншина. Харилцагчийн дэвтрийн "хаагдахад бүх бүртгэл алга болдог" шарх тэнд эмчлэгдэнэ — амласан ёсоор бид тэр төсөлдөө эргэж очно.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.