Ачааллж байна...
Түвшин 3: Итгэлтэй болох нь — тавтай морил. Энэ Түвшний нэр санамсаргүй биш: Түвшин 1-д та хэлний үндсийг, Түвшин 2-т барилгын материалыг эзэмшсэн бол одоо программист хүнийг итгэлтэй болгодог зүйлсийг эзэмшинэ — тэдгээрийн хамгийн эхнийх нь, хамгийн чухал нь: алдаатай зөв харьцах чадвар. Тиймээс энэ бүлгийг бид "Алдаатай найзлах" гэж нэрлэсэн — хэтрүүлэг биш: энэ гурван хичээлийн дараа улаан бичиг таны хувьд "аюулын дохио" байхаа больж "туслахын захидал" болно.
Үнэндээ энэ хичээл танд шинэ сэдэв биш. Эргээд тоолж үзье: та энэ сургалтын туршид SyntaxError, NameError, TypeError, ValueError, ZeroDivisionError, IndentationError, IndexError, KeyError — найман төрлийн алдаатай аль хэдийн танилцаж, мэдэгдлийг нь үг үгээр нь орчуулж уншсан. Бүлэг 1-д тавьсан суурь ойлголтоо ч саная: алдаа бол компьютер "би ойлгосонгүй" гэж хэлж байгаа хэрэг — таны тухай дүгнэлт биш, зааварчилгааны хаа нэгтээ тодорхой бус зүйл байна гэсэн мэдээлэл. Тэгвэл өнөөдөр юу шинэ вэ? Өдий хүртэл бид алдааны мэдэгдлийн зөвхөн сүүлчийн мөрийг нь уншиж ирсэн — гэтэл Python үнэндээ түүнээс хамаагүй их зүйл хэлдэг: алдаа гарах бүрд дэлгэцэд буудаг тэр хэдэн мөр улаан бичгийг бүхэлд нь traceback гэдэг бөгөөд түүний мөр бүр оношийн үнэтэй мэдээлэл тээдэг юм. Өнөөдөр бид traceback-ийг бүтнээр нь, эд ангиар нь задалж уншиж сурна — эмч рентген зураг уншдаг шиг.
Traceback-ийг ингэж төсөөлөөрэй: таны программ бол аялалд гарсан жуулчин — Бүлэг 3-ын дүрмээр дээрээс доош, мөрөөс мөр рүү аялдаг. Хаа нэгтээ зам тасарч, жуулчин цааш явж чадахгүй боллоо. Тэгэхэд Python юу хийдэг вэ: зүгээр л "явж чадсангүй" гээд дуугүй зогсдоггүй — ослын дэлгэрэнгүй тайлан бичиж үлдээдэг: аялал аль файлын, хэддүгээр мөрөнд тасрав, тэр мөрөнд яг юу бичээстэй байв, тэгээд тасралтын шалтгаан нь юу байв. Тэр тайлан бол traceback (үгчилбэл "мөрөөр нь ухрааж мөшгих" гэсэн утгатай — нэр нь ажлаа хэлж байна). Тайланг айж сандарсан хүн уншдаггүй — мөрдөгч уншдаг: тайван, дарааллаар, "хаана, юу, яагаад" гэсэн гурван асуултаар. Өнөөдрийн зорилго: таныг тэр мөрдөгч болгох.
Зориуд алдаатай жижиг программ бичье — hello.py биш, шинэ файл: tailan.py гэж нэрлээд:
python
ner = "Бат"
nas = "12"
print("Мэнд")
print(nas + 5)Run дарвал terminal-д дараах бичиг бууна:
Мэнд
Traceback (most recent call last):
File "C:\Users\Dulguun\Documents\python-hicheel\tailan.py", line 4, in <module>
print(nas + 5)
TypeError: can only concatenate str (not "int") to strОдоо энэ тайланг мөр мөрөөр нь задалъя — таны анхны бүтэн traceback-уншилт. Тэг дүгээр ажиглалт — traceback-ээс ч өмнө: дээр нь "Мэнд" хэвлэгдчихсэн байна! Энэ бол чухал гэрч: программ 3-р мөрөө амжилттай биелүүлээд дараа нь унасан — алдаа "программ бүхэлдээ буруу" гэсэн үг биш, аялал тодорхой цэг хүртэл хэвийн явсныг гарц өөрөө харуулдаг (бичиглэлийн давхаргын SyntaxError бол өөр: тэр аялал эхлэхээс өмнө илэрдэг тул түүний өмнө юу ч хэвлэгддэггүй — "уншиж чадаагүй" ба "биелүүлж чадаагүй" хоёр давхаргын ялгааг Бүлэг 5-д зааглаж байсныг сана). Эхний мөр: Traceback (most recent call last): — "тайлан эхэлж байна" гэсэн гарчиг; хаалтан доторх нь "хамгийн сүүлийн үйл явдал хамгийн доор нь" гэсэн уншлагын заавар — энэ зааврыг доор тусад нь дэлгэнэ. Хоёр дахь мөр: File "...tailan.py", line 4, in <module> — ослын хаяг: аль файл (урт зам нь таны компьютер дахь байршил — эхэндээ нүд эрээлжлэм харагдавч хэрэгтэй нь төгсгөлийн файлын нэр), line 4 — хэддүгээр мөр (VS Code-ын зүүн захын дугаартай шууд тулгана!), in <module> гэдэг нь "функцын дотор биш, файлын үндсэн түвшинд" гэсэн утгатай тэмдэглэгээ (function дотор унавал энд функцын нэр бичигддэг — тэр хэрэгтэй нюанстай доор таарна). Гурав дахь мөр: print(nas + 5) — ослын мөр өөрөө: Python эвдэрсэн мөрийг хуулж үзүүлдэг — файлаа нээлгүйгээр ч юу бичсэнээ хардаг цонх. Сүүлчийн мөр: TypeError: can only concatenate str... — онош: алдааны төрөл (хоёр цэгийн өмнөх) ба тайлбар (хойдох) — таны найман танилын хэл: nas дотор "12" гэсэн string байсан (2-р мөрийг хар — хашилттай!), string дээр int нэмэх гэж оролджээ.
Дөрвөн мөр — гурван асуултын хариулт: хаана (line 4), юу (print(nas + 5)), яагаад (TypeError: str дээр int...). Мөрдөгчийн ажил дууслаа — засвар нь ч тодорхой: 2-р мөрийн хашилтыг авах.
Хоёр дахь жишээ: доороос нь дээш — уншлагын алтан дүрэм. Гарчгийн "most recent call last" зааврыг ажил болгоё. Traceback урт байх үед хаанаас нь эхэлж уншдаг вэ? Хариулт: доороос нь. Учир нь тайлангийн хамгийн доод мөр нь үргэлж онош (алдааны төрөл ба тайлбар), түүний шууд дээрх хэсэг нь ослын яг цэг — өөрөөр хэлбэл хамгийн үнэтэй хоёр мэдээлэл ёроолд нь байдаг: дээрээс нь уншсан мөрдөгч "хаяг, хаяг, хаяг..." гээд явсаар оношид сүүлд нь хүрдэг бол доороос уншсан нь оношоо эхэлж аваад, хаягийг нь дараа нь тогтоодог. Дадал болгож томьёолъё: улаан бичиг харвал нүд шууд ёроол руу — сүүлчийн мөр юу гэж хэлж байна? Тэгээд нэг мөр дээшилж — line хэд? Энэ хоёр хөдөлгөөн ихэнх алдааг хоёр секундэд "хаана-юу-яагаад" болгодог.
Гурав дахь жишээ: function доторх осол — хоёр давхар тайлан. Traceback яагаад "ухрааж мөшгих" гэсэн нэртэйг одоо үзье. Ослыг function дотор гаргая:
python
def talbai(urt, urgun):
return urt * urgun
hariu = talbai("5", "3")
print(hariu)Run:
Traceback (most recent call last):
File "...tailan.py", line 4, in <module>
hariu = talbai("5", "3")
File "...tailan.py", line 2, in talbai
return urt * urgun
TypeError: can't multiply sequence by non-int of type 'str'Тайлан хоёр хаягтай боллоо! Доороос нь уншья (алтан дүрэм): онош — TypeError: string-ийг string-ээр үржүүлж болохгүй ("5" "3" — хоёулаа хашилттай: string int нь "давталт" гэж Бүлэг 5-ын туршилтаас мэднэ, харин string * string утгагүй). Нэг дээшилье: line 2, in talbai — осол talbai function-ий дотор, return-ий мөрөнд болжээ (in <module> байсан газар одоо функцын нэр — амласан нюанс!). Бас нэг дээшилье: line 4, in <module> — тэр function-ийг хэн дуудсан бэ: 4-р мөрийн talbai("5", "3") дуудлага. Уншлага нь: "Аялал 4-р мөрөөс talbai руу орж, 2-р мөрөнд осолдов" — тайлан ослын замыг бүхэлд нь мөшгиж өгч байна: дуудлагын гинж урт бол (function function-оо дуудсан...) хаяг бүр нэг мөр болж цувна. Оношлогооны нэг гүн ойлголт энд бий: осол 2-р мөрөнд илэрсэн ч жинхэнэ буруу нь 4-р мөрөнд (хашилттай argument өгсөн!) — тайлангийн доод хаяг "хаана илэрснийг", дээшилсэн хаягууд "хаанаас ирснийг" хэлдэг: илэрсэн газар нь үргэлж буруутай газар биш — мөрдөгч гинжээр нь дээшээ мөшгидөг учир нь энэ.
Дөрөв дэх жишээ: line дугаарын нэг заль — "жинхэнэ мөр нь дээхнэ". Мөрдөгчийн мэдвэл зохих нэг нарийн тохиолдол:
python
une = 1500
shirheg = int(input("Хэдэн ширхэг? ")
print(une * shirheg)Run:
File "...tailan.py", line 3
print(une * shirheg)
^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?Тайлан line 3-ыг заагаад, print-ийн мөрийг буруутгаж байна — гэтэл тэр мөр... бүрэн зөв! Жинхэнэ буруутан нь 2-р мөр: int(-ийн хаалт хаагдаагүй (тоолоод үз: гурван нээлт, хоёр хаалт). Юу болов: хаалт нээлттэй үлдэхэд Python "мөр үргэлжилсээр байна" гэж үзээд дараагийн мөрийг залгаж уншсаар... 3-р мөрөн дээр утга нийлэхээ болиход л зогссон — тиймээс "илэрсэн" газар нь 3, "үүссэн" газар нь 2. (Traceback-гүй, шууд File-аас эхэлж байгааг бас ажигла: бичиглэлийн давхаргын алдаа аялал эхлээгүй тул "мөшгих зам" гэж байхгүй — хаяг, мөр, ^ тэмдгээр заасан цэг, онош л байна.) Дүрэм болгож аваарай: заасан мөр нь гэм зэмгүй харагдвал — нэг, хоёр мөр дээшээ хар: хаагдаагүй хаалт, дутуу хашилт бол "доошоо нүүдэг" алдааны хаанууд. Азаар орчин Python ихэнхдээ шууд хэлдэг болсон: '(' was never closed гэсэн танил мэдэгдэл яг үүний тод хувилбар нь.
Хүсвэл туршаад үзээрэй: өөрийн аль нэг хуучин, ажилладаг программ дээр зориуд гурван өөр осол гаргаарай — нэг variable-ийн нэрийг эвдэж (NameError), нэг int()-ийг устгаж (TypeError), нэг индексийг хэтрүүлж (IndexError) — тэгээд гурван traceback-ийг мөрдөгчийн гурван асуултаар (хаана-юу-яагаад) уншаад, эвдсэнээ буцааж засаарай: аюулгүй орчны ослын дадлага — Бүлэг 7-ын Ctrl+C сургуулилтын мөрдөгч-хувилбар. Сонирхвол function доторх ослын гинжийг гурван давхар болгож үзээрэй (function function-оо дуудаад, тэр нь бас дуудаад) — traceback хэрхэн "давхарладагийг" нүдээрээ.
Энэ хичээлийн "алдаанууд" нь кодынх биш — тайлан уншигчийнх: traceback-тай харьцахдаа гаргадаг гурван зуршлын алдаа.
Алдаа 1: Уншилгүй дахин Run дарах. Хамгийн түгээмэл нь: улаан бичиг гармагц "аан алдаа гарчихлаа" гээд мэдэгдлийг уншилгүй кодоо ширтэж, таамгаар нэг юм өөрчлөөд дахин Run — болохгүй бол дахиад өөрчлөөд Run... Энэ "таамгийн тойрог" заримдаа азаар онодог ч ихэнхдээ цаг залгидаг — гэтэл хариулт нь дэлгэцэн дээр чинь бичээстэй байсан юм: line хэд, юу, яагаад. Дадал: Run-ы өмнө — унш: сүүлчийн мөр, тэгээд line. Хоёр секунд — таамгийн арван тойргоос хурдан.
Алдаа 2: Урт traceback-аас айж "бүгдийг" унших гэж оролдох. Эсрэг туйл: арван мөр улаан бичиг харагдахаар "энэ бүгдийг ойлгох ёстой юм байх" гээд дээрээс нь мөр мөргүй "судалж" эхлэх — дундах хаягуудын урт замууд, ойлгомжгүй нэрс нүд гувшаана. Үнэн нь: тайлангийн ихэнх мөр танд хэрэггүй — мөрдөгчид онош (ёроол) ба ослын цэг (түүний дээрх хаяг) л хэрэгтэй: дундах гинж зөвхөн "илэрсэн газар нь буруутай газар биш" гэсэн сэжиг төрөхөд л ашиглагддаг нөөц. Урт тайлан = том осол биш — зүгээр л урт дуудлагын гинж: айх юм нэмэгдээгүй, уншлагын дүрэм хэвээрээ.
Алдаа 3: Алдааг "би чадахгүй байна" гэж орчуулах. Хамгийн гүн нь — техникийн биш, сэтгэлийн: улаан бичиг дараалан гурав, дөрөв гарахаар "би энэ хичээлд тэнцэхгүй юм байна" гэсэн орчуулга толгойд аяндаа бууж эхэлдэг. Энэ орчуулга худал гэдгийг баримтаар хэлье: мэргэжлийн программистын ердийн ажлын өдөр хэдэн арван traceback-тай өнгөрдөг — алдааны тоо чадварын хэмжүүр биш: traceback-ийн тоо шинэ юм барьж байгаагийн хэмжүүр. Ялгаа нь ганцхан зүйлд: эхлэгч алдааг "шүүлт" гэж уншдаг, туршлагатан "мэдээлэл" гэж уншдаг — тэгээд та энэ хичээлээр яг тэр шилжилтийг хийж байна. Бүлэг 1-ийн амлалтыг Түвшин 3-ын хэлээр давтъя: алдаа бол таны эсрэг мэдүүлэг биш — таны төлөө бичигдсэн тайлан.
Traceback бол ослын тайлан: хаана (File, line), юу (эвдэрсэн мөрийн хуулбар), яагаад (сүүлчийн мөрийн онош) — гурван асуултын бэлэн хариулт.
Алтан дүрэм: доороос нь дээш — эхлээд сүүлчийн мөр (төрөл + тайлбар), тэгээд нэг дээшилж line; урт тайлангийн дундах гинж бол дуудлагын зам: доод хаяг "илэрсэн" газар, дээшилбэл "ирсэн" зам.
Осол function дотор бол in <module> оронд функцын нэр бичигдэж, дуудлагын гинж давхарлана — илэрсэн газар үргэлж буруутай газар биш: гинжээр дээшээ мөшги.
Заасан мөр гэм зэмгүй харагдвал нэг-хоёр мөр дээшээ хар: хаагдаагүй хаалт, дутуу хашилт "доошоо нүүдэг"; SyntaxError аялал эхлэхээс өмнө илэрдэг тул өмнө нь юу ч хэвлэгддэггүй.
Уншигчийн гурван дүрэм: Run-ы өмнө унш (таамгийн тойрогоос хурдан); тайланг бүгдийг биш — ёроол ба хаягийг; алдаа бол шүүлт биш — мэдээлэл.
Дараагийн хичээл бол энэ сургалтын хамгийн онцлог бүтээлүүдийн нэг: "Түгээмэл error-уудыг монголоор" — таны найман танилыг (SyntaxError-оос KeyError хүртэл) нэг дор эмхэтгэсэн лавлах хичээл: алдаа бүрийн жинхэнэ англи мэдэгдэл, монгол орчуулга, түгээмэл шалтгаанууд, засварын жор. Энэ бол "уншаад өнгөрдөг" биш "эргэж ирдэг" хуудас байх болно — хавчуурга тавьж болох газар чинь.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.