Ачааллж байна...
Энэ бүлэгт бид Түвшин 2-ын хоёр дахь том барилгын материалтай танилцана: function. Нэрийг нь сонсоод "шинэ, танихгүй юм" гэж бүү бодоорой — үнэндээ та function-уудтай анхны хичээлээсээ хойш өдөр бүр ажиллаж ирсэн: print() бол function, input(), int(), type(), range() — бүгд function. Та тэдгээрийг "хаалттай дуудагддаг багажууд" гэж таньдаг болсон: нэрийг нь бичээд, хаалт нээгээд, дуудахад — багаж ажлаа хийдэг. Өнөөдрийн шинэ зүйл нь ганцхан: тийм багажийг өөрөө хийж сурна. Print-ийг Python-ы бүтээгчид урьдчилан хийж өгсөн бол өнөөдрөөс эхлэн та өөрийн гэсэн, өөрийн нэртэй, өөрийн ажилтай "багажуудыг" бүтээж, тэдгээрийг print шигээ дуудаж хэрэглэдэг болно.
Тэгвэл function гэж чухам юу вэ? Хамгийн энгийнээр: function бол нэр өгсөн кодын багц юм — хэдэн мөр кодыг нэг дор багцлаад, багцад нэр өгөөд, хожим тэр нэрийг дуудах бүрд багц доторх мөрүүд биелдэг. "Юунд хэрэгтэй юм бэ" гэдгийг нэг өгүүлбэрээр хэлбэл: давталт (loop) нэг багц кодыг нэг газраа олон удаа биелүүлдэг байсан бол function нэг багц кодыг олон газраас, хүссэн үедээ биелүүлэх боломж өгдөг. Хоёул "давталтын дайсан" — хуулж буулгалттай тэмцдэг зэвсгүүд, гэхдээ өөр өөр талаас нь. Энэ ялгааг доор жишээн дээр тод харна.
Function-ий сонгодог зураг бол бичиж хадгалсан хоолны жор юм. Бүлэг 1-ийг саная: программ бол жор, компьютер бол түүнийг үг үсэгчлэн дагадаг тогооч. Одоо төсөөлөөрэй — танай гэрт бууз хийх нарийн дараалал бий: гурил зуурна, фарш бэлдэнэ, хийж жигнэнэ... нийт арван алхам. Хэрэв та энэ арван алхмыг бууз хийх бүрдээ тогоочдоо нэг бүрчлэн хэлдэг бол — залхуутай, мартах алдах эрсдэлтэй. Ухаалаг зам: арван алхмаа нэг удаа цаасан дээр бичиж, дээр нь "БУУЗНЫ ЖОР" гэсэн гарчиг тавиад, тогоочийн жорын дэвтэрт хийчих. Түүнээс хойш танд ганц үг хангалттай: "Бууз хий" — тогооч дэвтрээ нээж, жороо олж, арван алхмыг гүйцэтгэнэ. Маргааш дахиад "Бууз хий" — дахин гүйцэтгэнэ.
Энэ зурагт function-ий бүх эд анги байна. Жороо бичиж дэвтэрт хийх нь function тодорхойлох (define) — нэг л удаа хийгддэг ажил. "Бууз хий" гэж захих нь function дуудах (call) — хэдэн ч удаа, хэзээ ч хийж болно. Тэгээд нэг амин чухал ажиглалт: жор дэвтэрт орсноор хоол болчихдоггүй — бичих ба захих хоёр тусдаа үйл явдал: жор нь дэвтэртээ чимээгүй хэвтэж байдаг, зөвхөн захиалга ирэх мөчид л тогооч ажилдаа ордог. Энэ "бичих ≠ биелэх" ялгаа бол өнөөдрийн хичээлийн хамгийн олон эргэлзээ төрүүлдэг цэг тул жишээн дээрээ ил гаргая.
Мэндчилгээний "жор" бичье:
python
def mendchilgee():
print("Сайн байна уу!")
print("Тавтай морил")
mendchilgee()Үр дүн:
Сайн байна уу!
Тавтай морилМөр бүрээр задалъя. def — Python-ы нөөцөлсөн үг, define ("тодорхойлох") гэдгийн товчлол: "одоо жор бичиж эхэлж байна" гэсэн зарлал. mendchilgee — жорын маань нэр: бид өөрсдөө өгсөн, нэрийн хичээлийн бүх дүрэм (үсэг-тоо-доогуур зураас, snake_case...) энд бүрэн хүчинтэй. () — хоосон дугуй хаалт: одоохондоо "ёслолын" мэт харагдаж болох ч удахгүй (дараагийн хичээлд) энэ хаалт жинхэнэ ажилтай болно — өнөөдөртөө "function-ий нэрийн ард үргэлж хаалт явдаг" гэсэн дүрэм болгож тогтооё. Мөрийн төгсгөлд — таны сайн таньдаг хоёр цэг, дараагийн мөрүүдэд — таны сайн таньдаг догол мөр: if, for, while-тай яг ижил хуулиар, шигдсэн мөрүүд нь function-ий бие буюу жорын алхмууд болно. Шигдэлт дуусмагц жор дуусна.
Одоо хамгийн чухал ажиглалт: файлын сүүлчийн мөр — mendchilgee() — байгаагүй бол юу болох байсан бэ? Юу ч хэвлэгдэхгүй байсан. Def-ийн багц бол зөвхөн жорыг дэвтэрт бичих үйлдэл: Python def-ийг уншаад "аан, mendchilgee гэдэг нэртэй, ийм биетэй жор байх юм байна" гэж цээжилдэг — гэхдээ биелүүлдэггүй. Биелэлт зөвхөн дуудлагын мөчид: mendchilgee() гэсэн мөрөнд хүрмэгц Python дэвтрээ нээж, тэр нэрийн жороо олж, биеийг нь дээрээс доош гүйцэтгэдэг. Дуудлагын бичиглэлийг ажигла: нэр + хаалт — print() дууддаг байсантай чинь яг ижил хэлбэр. Тийм ээ: та долоон бүлгийн турш "багаж дуудаж" ирсэн тэр л хөдөлгөөнөө одоо өөрийн бүтээсэн багаж дээрээ хийж байна.
Дуудлагыг олон болгоё — function-ий хүч эндээс эхэлнэ:
python
def mendchilgee():
print("Сайн байна уу!")
print("Тавтай морил")
mendchilgee()
mendchilgee()
mendchilgee()Үр дүн: хоёр мөрт мэндчилгээ гурван удаа цувна. Жор нэг — захиалга гурав. Биеийг нь өөрчлөх хэрэг гарвал? Нэг л газар засна — гурван дуудлага бүгд шинэ хувилбараар ажиллана. Танил зарчим сэргэж байна уу: "нэг мэдээлэл нэг л газар амьдрах ёстой" — Бүлэг 4-т variable-ийн тухай хэлж байсан энэ зарчим одоо кодод өөрт нь үйлчилж эхэллээ. Программистууд үүнийг DRY зарчим гэдэг — Don't Repeat Yourself, "өөрийгөө бүү давт": ижил код хоёр газар байвал нэг нь илүүц.
Хоёр дахь жишээ: өмнө ба хойно — DRY ажил дээрээ. Function-гүй амьдралын жинхэнэ өвдөлтийг нэг харцгаая. Тоглоомын программ гурван өөр газраа "хуваарийн зураас" хэвлэдэг гэж бодъё:
python
print("==============================")
print(" ТОГЛООМ ЭХЭЛЛЭЭ")
print("==============================")
print("Тоглолт явагдаж байна...")
print("==============================")
print(" АМЖИЛТ ХҮСЬЕ")
print("==============================")"Хүрээ" хэвлэдэг хоёр мөр (зураас-гарчиг-зураас гэсэн хэв маяг) хоёр удаа хуулагдчихлаа — гуравт, дөрөвт хэрэглэх тусам хуулбар өснө, зураасын уртыг өөрчлөх хэрэг гарвал бүх газраа марталгүй засах ёстой болно. Одоо function-тэй хувилбар:
python
def zuraas():
print("==============================")
zuraas()
print(" ТОГЛООМ ЭХЭЛЛЭЭ")
zuraas()
print("Тоглолт явагдаж байна...")
zuraas()
print(" АМЖИЛТ ХҮСЬЕ")
zuraas()Үр дүн яг ижил — гэхдээ зураасны "мэдлэг" одоо нэг л газар амьдардаг: уртыг нь өөрчлөх бол def доторх ганц мөрийг засна, дөрвөн дуудлага автоматаар шинэчлэгдэнэ. Мөн нэг далд ашиг: zuraas() гэсэн нэр нь кодыг уншигчид "энд зураас татна" гэж үгээр хэлж өгч байна — print("====...") мөрийг нүдээрээ ялгаж уншихаас хөнгөн. Function бол зөвхөн давталт хэмнэгч биш — кодод нэр томьёо нэмдэг хэрэгсэл: сайн нэртэй function-уудаас бүтсэн программ бараг өгүүлбэр шиг уншигддаг.
Гурав дахь жишээ: function дотор танил бүх зүйл ажиллана. Жорын биед юу бичиж болох вэ — бүх юм: variable, if, loop... Функцын бие бол жирийн л кодын багц:
python
def toolol():
print("Хөөргөлтөд бэлдэв!")
for i in range(5, 0, -1):
print(i)
print("Хөөрлөө!")
toolol()
print("---")
toolol()Үр дүн: пуужингийн тоолол хоёр удаа, хооронд нь зураас. Range-ийн хичээлийн жишээ маань "жор" болоод дахин ашиглагдахуйц боллоо. Шигдэлтийн давхаргыг ажигла: for-ын толгой function-ий биед (нэг шат), for-ын өөрийнх нь бие хоёр шатанд — бүтэц бүтцийн дотор орохоор шат нэмэгддэг танил дүрэм. Мөн нэг зүйлийг тодотгоё: toolol дотор үүссэн i variable нь function-ий "дотоод ажилтан" — энэ сэдвээр хожим нарийн ярих зүйл бий, өнөөдөртөө "function бол өөрийн гэсэн ажлын өрөөтэй" гэсэн сэрэмж л аваад явъя.
Дөрөв дэх жишээ: тодорхойлолт дуудлагаасаа өмнө. Нэг чухал дэс дарааллын дүрмийг ил гаргая:
python
mendchilgee()
def mendchilgee():
print("Сайн байна уу!")Python:
NameError: name 'mendchilgee' is not definedТанил NameError — Бүлэг 4-ийн "хайрцаг эхэлж төрдөг" дүрмийн function хувилбар: Python дээрээс доош уншдаг тул 1-р мөрөнд хүрэхдээ mendchilgee гэдэг жорыг дэвтэртээ хараахан бичээгүй байв — тийм нэр танихгүй. Def нь дуудлагаасаа дээр байх ёстой. Эндээс программын файлын нэг тогтсон зохион байгуулалт урган гардаг: жорын дэвтэр — дээрээ, захиалгууд — доороо: файлын эхэнд def-үүд цуварч, доод хэсэгт нь "жинхэнэ ажил" (дуудлагууд) явдаг. Энэ дэглэмтэй файл уншихад ч эвтэй: "энэ программ ямар багажуудтай вэ" гэдгийг эхнээс нь, "тэднийг яаж хэрэглэдэг вэ" гэдгийг төгсгөлөөс нь хардаг.
Хүсвэл туршаад үзээрэй: өөрийн "гарын үсэг" function бичээрэй — нэр, дуртай зүйл, уриа үгээ хэвлэдэг гурван мөртэй жор — тэгээд гурван газраас дуудаарай. Сонирхвол zuraas() жишээн дээр зураасны мөрийг өөрчлөөд (тэмдэгт нь, урт нь) нэг засвар дөрвөн газар "туссаныг" нүдээрээ шалгаарай — DRY-ийн амтыг мэдрэх хамгийн богино зам.
Алдаа 1: Дуудахдаа хаалтаа мартах. Хамгийн түгээмэл нь — мэдэгдэлгүй, чимээгүй:
python
def mendchilgee():
print("Сайн байна уу!")
mendchilgeeҮр дүн: юу ч хэвлэгдэхгүй — алдаа ч гарахгүй. Хаалтгүй mendchilgee гэдэг нь Python-д "дуудлага" биш: тэр жорыг биелүүлэлгүй, зүгээр л "ийм нэртэй жор байна шүү" гэж дурдаад өнгөрсөнтэй адил (нарийн ярьвал: function-ий нэр бол өөрөө нэг утга бөгөөд түүнийг variable шиг "дурдаж" болдог — энэ гүн чадварын учир хожмын нутаг). Дуудлага гэдэг нь нэр + хаалт: хаалт бол "одоо ажилла!" гэсэн товч. Оношлогооны дүрэм: function чинь "дуудагдсан юм шиг мөртлөө юу ч хийхгүй" бол хаалтаа шалга — энэ бол type()-ийн "print-гүй ганцаардсан асуулт"-ын ах дүү, чимээгүй замхралын гэр бүлийн гишүүн.
Алдаа 2: def-ийн мөрөнд хаалт, хоёр цэгээ гээх. Бичиглэлийн иж бүрдэл эвдэрвэл:
python
def mendchilgee:
print("Сайн байна уу!")Python:
SyntaxError: expected '('Орчуулбал: "хаалт байхыг хүлээж байсан." Def-ийн мөрийн иж бүрдэл нь def + нэр + () + хоёр цэг — дөрвөн эд анги, аль нь ч дутуу бол Python шууд зогсооно: хаалт дутвал дээрх мэдэгдэл, хоёр цэг дутвал таны Бүлэг 6-аас таньдаг SyntaxError: expected ':'. Хоёул "гарвал шууд, тодоор" гардаг аюулгүй давхаргын алдаанууд — засвар нь механик: иж бүрдлээ гүйцээ.
Алдаа 3: Биеэ шигдүүлэхээ мартах — гурав дахь танил. if, for дээр үзсэн хууль def-д ч хүчинтэй:
python
def mendchilgee():
print("Сайн байна уу!")Python:
IndentationError: expected an indented block after function definition on line 1"1-р мөрийн function-ий тодорхойлолтын дараа шигдсэн багц байхыг хүлээж байсан" — if statement, for statement гэж хэлдэг байсан газар нь function definition болж солигдсоноос өөр шинэ зүйлгүй. Хоёр цэгээр төгссөн мөр бүр ард нь шигдсэн бие нэхдэг — энэ ганц дүрэм одоо дөрвөн бүтцийг (if/elif/else, for, while, def) бүгдийг нь хамарч байна: Python-ы бичиглэлийн ертөнц үнэндээ цөөхөн дүрмээс бүтдэгийн нотолгоо.
Function бол нэр өгсөн кодын багц — "дахин ашиглаж болох жор": нэг удаа тодорхойлоод (def), хэдэн ч удаа дууддаг (нэр + хаалт).
Def бол зөвхөн "жорыг дэвтэрт бичих": бие нь дуудлагын мөч хүртэл биелдэггүй — бичих ≠ биелэх.
Дуудлага нь нэр + хаалт: хаалтгүй нэр бол чимээгүй "дурдлага" — function ажиллахгүй, алдаа ч гарахгүй.
DRY зарчим: ижил код хоёр газар байвал нэг нь илүүц — function нь кодын мэдлэгийг нэг газар төвлөрүүлж, нэрээрээ кодыг уншигдахуйц болгодог.
Def-ийн иж бүрдэл: def + нэр + () + хоёр цэг + шигдсэн бие; тодорхойлолт дуудлагаасаа дээр байрлана — "жорын дэвтэр дээрээ, захиалга доороо."
Print, input, int, type, range — таны хэрэглэж ирсэн бүхэн function байсан: одоо та тэдний "мэргэжил нэгтэн" боллоо.
Дараагийн хичээлд function-ий хоосон хаалт маань амилна: parameter — жор руу "орц" дамжуулах арга. "Бууз хий" биш "гурван хүний бууз хий", mendchilgee() биш mendchilgee("Бат") — function-д мэдээлэл өгч, өгсөн мэдээллээр нь ажиллуулдаг болно. Мөн эхлэгч бүрийн хольж соливчдог parameter ба argument гэсэн хоёр үгийн ялгааг тэнд тайван задална.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.