Ачааллж байна...
Өмнөх хичээлд бид function-ий хоосон хаалтыг "ёслолын мэт харагдаж болох ч удахгүй жинхэнэ ажилтай болно" гэж амласан. Өнөөдөр тэр өдөр. Эхлээд өмнөх хичээлийн mendchilgee-гийн нэг хязгаарыг ил гаргая: тэр function хэдэн ч удаа дуудагдсан яг ижил зүйл хийдэг — "Сайн байна уу!" гэж л хэлнэ. Гэтэл бидний өдөр бүр хэрэглэдэг function-ууд тийм биш шүү дээ: print() дуудлага бүрдээ өөр зүйл хэвлэдэг — учир нь бид хаалтанд нь юу хэвлэхийг өгдөг: print("Сайн уу"), print(score), print(2 + 3). Range() дуудлага бүрдээ өөр тасалбар үйлдвэрлэдэг — бид хаалтанд нь хил заадаг учраас. Өөрөөр хэлбэл жинхэнэ хүчирхэг function гэдэг нь "үргэлж яг ижил ажил" биш — "нэг төрлийн ажлыг, өгсөн орцоор нь" хийдэг зүйл юм. Function-д орц өгдөг тэр механизмыг parameter гэдэг — өнөөдрийн ганц сэдэв энэ.
Мөн энэ хичээлд бид нэг үгийн будилааныг эхнээс нь цэгцэлнэ. Энэ сэдвийн орчимд хоёр төстэй үг зэрэгцэн явдаг: parameter ба argument. Дэлхийн бүх эхлэгч энэ хоёрыг хольж ярьдаг — үнэнийг хэлэхэд туршлагатай программистууд ч ярианы дунд сольчихдог, тэгээд ихэнхдээ хэн ч гомдоллодоггүй. Гэхдээ ялгааг нь нэг удаа цэвэрхэн ойлгочихвол алдааны мэдэгдлүүд (яг өнөөдөр үзэх TypeError чинь argument гэдэг үгээр ярьдаг!) болон ирээдүйн бүх унших материал чинь илүү тод болно. Тиймээс бид яарахгүй, хоёр үгийг зүйрлэлээсээ л салгаж авч явна.
Буузны жороо эргэж нээе — гэхдээ энэ удаад нэг ухаалаг сайжруулалттайгаар. Өмнөх жор маань "500 грамм фарш бэлд" гэж хатуу бичээстэй байсан бол шинэ жор дээр ингэж бичье: "___ хүний тооцоотой фарш бэлд" — хоосон нүхтэй, дүүргэхийг хүлээсэн жор. Одоо захиалга өгөхдөө нүхийг нь дүүргэж захина: "Бууз хий — дөрвөн хүнд." Тогооч жорынхоо ___ гэсэн нүх бүрд 4-ийг орлуулж уншаад ажиллана. Маргааш "Бууз хий — арван хүнд" гэвэл мөн л нэг жор — өөр тооцоотой ажиллана. Жор нэг — гүйцэтгэл нь орцоороо өөр өөр: энэ л parameter-ийн бүх санаа.
Одоо хоёр үгээ энэ зургаас салгаж авъя. Жорын бичиг дэх нүх — "___ хүний" гэсэн, нэртэй, дүүргэгдэхийг хүлээсэн хоосон зай — энэ бол parameter: тодорхойлолтод (def-д) бичигддэг, "энд утга ирнэ" гэсэн байрлал. Харин захиалгын үед нүхэнд хийж өгсөн бодит утга — 4, эсвэл 10 — энэ бол argument: дуудлагад бичигддэг, тухайн нэг гүйцэтгэлийн жинхэнэ орц. Нэг өгүүлбэрт: parameter — жор дээрх нүх, argument — нүхэнд хийсэн жинхэнэ юм. Санахад бүр амар холбоос: parameter гэдэг үг def-тэй хамт (хоёул "тодорхойлолтын" талд), argument нь дуудлагатай хамт амьдардаг. Мөн энэ хоёрын харилцаа танд аль хэдийн танил гэдгийг хэлье: нүхийг дүүргэх үйлдэл бол үнэндээ variable-д утга оноох явдал юм — parameter бол function эхлэх мөчид автоматаар үүсдэг variable, argument нь түүний анхны утга нь болдог. Хайрцагны хэлээр: дуудлага бүрийн эхэнд Python шинэ хайрцаг (parameter-ийн нэртэй) гаргаж ирээд, дотор нь таны өгсөн утгыг (argument) хийгээд, биеийг нь ажиллуулдаг.
Mendchilgee-гээ "нүхтэй" болгоё:
python
def mendchilgee(ner):
print("Сайн байна уу,", ner)
print("Тавтай морил!")
mendchilgee("Бат")
mendchilgee("Сараа")Үр дүн:
Сайн байна уу, Бат
Тавтай морил!
Сайн байна уу, Сараа
Тавтай морил!Задалъя. Def-ийн мөрөнд хоосон байсан хаалт дотор одоо ner гэсэн нэр зогсож байна — энэ бол parameter: "энэ жорыг дуудахдаа нэг утга өгөх ёстой, тэр утгыг би бие дотроо ner гэж нэрлэж хэрэглэнэ" гэсэн зарлал. Биеийн дотор ner нь жирийн variable шигээ хэрэглэгдэж байгааг ажигла — print-ийн таслал хэлбэрээр (Бүлэг 5-ын танил) хэвлэгдэж байна. Дуудлагуудыг хар: mendchilgee("Бат") — хаалтан доторх "Бат" бол argument. Эхний дуудлагыг мөшгье: Python дуудлагыг хараад жороо олж → ner нэртэй шинэ хайрцаг үүсгэж, дотор нь "Бат"-ыг хийж → биеийг дээрээс доош гүйцэтгэнэ: ner-ийн оронд "Бат" ажиллаж "Сайн байна уу, Бат" гарлаа. Хоёр дахь дуудлагад мөн үйл явц шинээр давтагдана — энэ удаад ner дотор "Сараа". Нэг жор, хоёр орц, хоёр өөр гүйцэтгэл: өмнөх хичээлийн "яг ижил ажилтай" function маань хувь хүнд хандаж чаддаг боллоо.
Нэг чухал асуулт: ner-д ямар утга очих нь юугаар шийдэгддэг вэ? Байрлалаар. "Бат" гэдэг string нь ner-тэй ямар нэг "утгын" холбоогүй — зүгээр л эхний argument нь эхний parameter-т очдог журамтай. Энэ нь ганц нүхтэй үед мэдрэгдэхгүй ч олон нүхтэй болмогц гол дүрэм болно — одоо тийшээ явцгаая.
Хоёр дахь жишээ: олон parameter. Жор олон нүхтэй байж болно — таслалаар зааглана:
python
def zahialga(hool, shirheg):
print("Захиалга:", hool)
print("Ширхэг:", shirheg)
print("Нийт үнэ:", shirheg * 1500)
zahialga("хуушуур", 4)Үр дүн:
Захиалга: хуушуур
Ширхэг: 4
Нийт үнэ: 6000Хоёр parameter (hool, shirheg) — хоёр argument ("хуушуур", 4). Байрлалын журам ажиллаж байна: эхний argument → эхний parameter (hool = "хуушуур"), хоёр дахь → хоёр дахь (shirheg = 4). Биеийн гурав дахь мөрөнд shirheg тооцоололд орж байгааг ажигла — parameter бол бүрэн эрхт variable тул түүнтэй юу ч хийж болно. Одоо байрлалын журмын хариуцлагатай талыг харцгаая — argument-уудаа сольж өгвөл:
python
zahialga(4, "хуушуур")Python дуулгавартай биелүүлнэ: hool = 4, shirheg = "хуушуур" — эхний хоёр мөр "Захиалга: 4", "Ширхэг: хуушуур" гэж утгагүй боловч алдаагүй хэвлэгдээд... гурав дахь мөрөнд "хуушуур" * 1500 гэсэн үйлдэл дээр TypeError гарна (string-ийг ийм том тоогоор үржүүлж болдоггүй нь аз — үржигдэж болдог байсан бол бүр ч зальтай гажуудал гарах байсан). Сургамж: Python argument-уудын утгыг "ойлгодоггүй" — зөвхөн байрлалыг нь тоолдог: зөв дараалал бол таны хариуцлага. Хамгаалах дадал: дуудлага бичихдээ def-ийн мөрийг нүдээрээ (эсвэл VS Code-ын жижиг зөвлөгөө цонхоор — дуудлага бичиж эхлэхэд эдитор parameter-уудын нэрсийг харуулдаг!) харьцуулж, орцуудынхаа дарааллыг тулга.
Гурав дахь жишээ: loop дотроос дуудах — хүчний үржвэр. Function ба давталт хоёр ямар гоё хоршдогийг үзье. Ангийнхаа хүүхдүүдэд нэг бүрчлэн гэрчилгээ хэвлэе:
python
def gerchilgee(ner, ono):
print("------------------------------")
print("ГЭРЧИЛГЭЭ")
print(ner, "танд олгов")
print("Оноо:", ono)
print("------------------------------")
gerchilgee("Бат", 95)
gerchilgee("Сараа", 88)
gerchilgee("Дорж", 91)Гурван дуудлага — гурван бүрэн гэрчилгээ: арван таван мөр хэвлэгдэхэд бид гуравхан мөр захиалга бичлээ. Гэрчилгээний хэлбэр (таван мөрт бүтэц) нэг газраа, агуулга нь (нэр, оноо) дуудлага бүрд — DRY зарчмын parameter-тэй хувилбар: өмнөх хичээлд "ижил кодыг" нэгтгэдэг байсан бол одоо "бараг ижил кодыг" нэгтгэж чаддаг боллоо — ялгаатай хэсгүүд нь нүх болж жорондоо суудаг. Энэ бол function-ий жинхэнэ ур чадвар: давтагдаж буй хэв маягийг олж хараад — тогтмол хэсгийг нь бие болго, хувьсдаг хэсгийг нь parameter болго.
Дөрөв дэх жишээ: variable-ийг argument болгож өгөх. Argument заавал шууд бичсэн утга байх албагүй — хайрцаг ч байж болно:
python
def ugtaal(ner):
print("Тавтай морил,", ner)
zochnii_ner = input("Таны нэр хэн бэ? ")
ugtaal(zochnii_ner)Хэрэглэгч Оюунаа гэж хариулбал "Тавтай морил, Оюунаа" гарна. Энд нэг нарийн зүйл болж байна: дуудлагын мөчид Python zochnii_ner хайрцгийг онгойлгож утгыг нь ("Оюунаа") аваад, ner хайрцганд хуулж хийдэг — Бүлэг 4-ийн "хайрцагнаас хайрцагт хуулах" яг тэр үйлдэл. Хоёр нэр (zochnii_ner ба ner) өөр байж болдгийг ажигла — бүр ихэвчлэн өөр байдаг: гаднах ертөнц утгаа юу гэж нэрлэх нь жорын дотоод нэрээс хамааралгүй. Энэ салангид байдал бол function-ий сайхан чанар: жор бичигч дотоод нэрсээ өөрийн дураар сонгодог, дуудагч гаднах нэрсээ өөрийнхөөрөө — уулзвар дээр зөвхөн утга л дамждаг.
Хүсвэл туршаад үзээрэй: өмнөх хичээлийн zuraas() function-оо urt гэсэн parameter-тэй болгоод, print("=" * urt) гэсэн биетэй болгож үзээрэй (string-ийг тоогоор үржүүлдэг тэр хөгжилтэй чадвар — Бүлэг 5-ын туршилтын амттан — энд жинхэнэ ажлаа оллоо): zuraas(10), zuraas(30) хоёр өөр урттай зураас татна. Сонирхвол gerchilgee-г loop-той хослуулж, гурван дуудлагыг for давталтаар хийж болох эсэхийг бодоод үзээрэй — жинхэнэ цэвэрхэн шийдэл нь Бүлэг 10-ын list-ийг хүлээж байгаа ч, эргэцүүлэл нь өөрөө үнэтэй.
Алдаа 1: Argument дутуу өгөх. Хоёр нүхтэй жорд нэг л орц өгвөл:
python
def zahialga(hool, shirheg):
print("Захиалга:", hool, "-", shirheg, "ширхэг")
zahialga("хуушуур")Python:
TypeError: zahialga() missing 1 required positional argument: 'shirheg'Орчуулбал: "zahialga() дуудлагад 1 шаардлагатай байрлалын argument дутуу байна: 'shirheg'." Энэ мэдэгдлийг үг үгээр нь амталъя — учир нь энэ бол таны алдааны мэдэгдэл унших чадварын нэг том шалгуур. missing 1 — хэдэн орц дутууг тоолж хэлж байна; positional argument — "байрлалын argument": бидний үзсэн "байрлалаар нь тааруулдаг" журмын албан нэр; 'shirheg' — аль нүх хоосон үлдснийг нэрээр нь зааж байна. Python дутууг таамаглаж нөхдөггүй — Бүлэг 1-ийн "компьютерт нөхөх ухаан байхгүй" үнэн энд ажиллаж байна: жор хоёр орц нэхсэн бол хоёуланг нь өг. Мөн анзаараарай — мэдэгдэл argument гэдэг үгийг хэрэглэж байна: хичээлийн эхэнд "энэ хоёр үгийг ялгаж сурвал алдааны мэдэгдлүүд тод болно" гэж амласан маань биелж эхэллээ. Урвуу тохиолдол нь ч бий: zahialga("хуушуур", 4, 99) гэж илүү өгвөл TypeError: zahialga() takes 2 positional arguments but 3 were given — "2 авдаг байтал 3 өглөө": мөн л тоолоод, мөн л шууд хэлнэ. Дутуу ч, илүү ч — тоо таарахгүй бол function ажиллаж эхлэхээсээ өмнө зогсдог: биеийн нэг ч мөр биелэхгүй.
Алдаа 2: Parameter-ийг function-ий гадна дуудах. Жорын дотоод нэрийг гаднаас нь хэрэглэх гэвэл:
python
def mendchilgee(ner):
print("Сайн байна уу,", ner)
mendchilgee("Бат")
print(ner)Python:
NameError: name 'ner' is not defined"Яахаараа?! Сая л ner дотор 'Бат' байсан шүү дээ" — гэхдээ өмнөх хичээлийн "function бол өөрийн гэсэн ажлын өрөөтэй" гэсэн сэрэмж энд биежиж байна: parameter бол function-ий дотоод variable — дуудлага эхлэхэд төрж, дуудлага дуусахад ажлын өрөөтэй нь хамт алга болдог. Function дуусмагц ner гэдэг хайрцаг хаана ч байхгүй тул гаднах print түүнийг олсонгүй. Энэ "дотоод ертөнцийн" дүрэм эхэндээ хатуу санагдаж болох ч агуу зорилготой: function бүр өөрийн өрөөнд ажилладаг учраас таны бичсэн function өөр газрын variable-уудтай санамсаргүй мөргөлддөггүй — өрөө өрөөндөө, эмх цэгцтэй. "Тэгвэл function дотроос гадагш утга яаж гаргах юм бэ?" — маш зөв асуулт: түүний хариулт бол return — дараагийн хичээлийн гол баатар.
Алдаа 3: Def-дээ parameter зарлачихаад дотор нь input асуух. Хоёр аргыг давхарласан будлиан:
python
def ugtaal(ner):
ner = input("Таны нэр хэн бэ? ")
print("Тавтай морил,", ner)
ugtaal("Бат")Алдааны мэдэгдэлгүй — гэхдээ ажиглаарай: дуудагч "Бат" гэж өгсөн атал function дотроо ner-ийг input-аар дарж бичээд (Бүлэг 4: шинэ утга хийхэд хуучин нь алга болдог) хэрэглэгчээс дахин асуулаа — өгсөн argument хогийн саванд очив. Энэ нь ихэвчлэн хоёр хэв маягийг хольсноос үүсдэг: мэдээллийг function гаднаас нь авах уу (parameter — дуудагч нь хариуцна), дотроо асуух уу (input — function өөрөө хариуцна). Хоёул зөв арга, гэхдээ нэгийг нь сонго: ерөнхий зөвлөмж бол parameter-ийг сонгох — "асуултаа гадаа нь, ажлаа дотор нь" гэсэн хуваарь: function чинь input-аас хамааралгүй болохоор түүнийг ямар ч орчинд (хэрэглэгчгүй, өөр программын дундаас ч) дахин ашиглаж болдог. Function бичихдээ өөрөөсөө асуу: "энэ мэдээллийг хэн мэдэх ёстой вэ — дуудагч уу, хэрэглэгч үү?" — хариулт нь parameter/input сонголтыг чинь хийж өгнө.
Parameter бол def-ийн хаалтан дахь "нүх" — function эхлэхэд автоматаар үүсдэг дотоод variable; argument бол дуудлагад өгсөн бодит утга — нүхний анхны агуулга: жор дээрх нүх ба нүхэнд хийсэн юм.
Олон parameter таслалаар зарлагдаж, argument-ууд байрлалаараа тааруулагддаг — дараалал бол таны хариуцлага, Python утгыг "ойлгодоггүй".
Function-ий ур чадвар: давтагдах хэв маягийн тогтмол хэсгийг бие болго, хувьсдаг хэсгийг parameter болго.
Argument дутвал/илүүдвэл TypeError — мэдэгдэл нь дутууг тоолж, нэрлэж хэлдэг; function биеэ эхлүүлэхээсээ өмнө зогсдог.
Parameter бол function-ий дотоод ертөнцийн иргэн: гаднаас нь дуудвал NameError — дотоодоос гадагш утга гаргах хэрэгсэл нь дараагийн хичээлийн return.
Дараагийн хичээл бол Бүлэг 8-ын хамгийн чухал нь: return — function-оос хариу авах. Print бол "хэлэх", return бол "гардуулах" — энэ хоёрын ялгаа бол бүхэл сургалтын хамгийн олон эхлэгчийг будилуулдаг сэдэв гэдгийг шууд хэлье: тиймээс бид түүнд яарахгүй, олон жишээтэй, бүтэн хичээл зориулна. Int()-ээс та хариу авч хэрэглэдэг байсныг санаж байна уу — өөрийн function-ууд чинь тэгж "хариу гардуулдаг" болно.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.