Ачааллж байна...
Өчигдөр санаа — өнөөдөр бичиглэл. Бид өнөөдөр таны анхны зураг төслийг зохионо: Nohoi class — "нохой болгон нэртэй, настай байна" гэсэн тодорхойлолт — тэгээд түүнээсээ анхны жинхэнэ нохойгоо "угсарна". Жишээ нь яагаад нохой вэ: учир нь нохой бол "олон талын мэдээлэлтэй нэг юм"-ын хамгийн энгийн, хамгийн дулаахан дүр — тэгээд дэлхийн программчлалын сургалтуудын хагас нь яг нохойгоор эхэлдэг уламжлалтай: та олон улсын "нэг ангийн" сурагчидтай нэгдэж байна гэсэн үг.
Өнөөдрийн бичиглэлд гурван шинэ зүйл бий: class гэдэг үг (амархан — def-ийн ах дүү), init гэдэг сонин нэр (хэв дарагч — өчигдрийн амлалт), тэгээд self гэдэг жижигхэн үг. Сүүлчийнхийг нь онцгойлон, шударгаар урьдчилъя: self бол дэлхийн бүх Python эхлэгчийг будилуулдаг үг — "яагаад заавал бичдэг юм", "энэ чинь хаанаас утгаа авдаг юм" гэсэн эргэлзээ хүн бүрд төрдөг: танд төрвөл та яг зөв замаараа, хүн бүрийн явдаг шатаар явж байна — тиймээс бид түүнд яарахгүй, тусгай хэсэг зориулж, олон талаас нь эргүүлж үзнэ. Мөн нэг тайвшрал: өнөөдрийн бүх "шинэ" бичиглэл үнэндээ хуучин эд ангиудаас угсрагдана — хоёр цэг, шигдэлт, def, parameter, цэгэн хандалт: шинэ нь зөвхөн утга нь.
Өчигдрийн үйлдвэрээ эргэж очъё — өнөөдөр инженерийн өрөөнд орж, зураг төслийн цаасыг өөрсдөө зурна. Цаасан дээр юу бичигддэг байсан бэ: нэг — загварын нэр ("Нохой загвар"); хоёр — угсрах заавар: "шинэ нохой угсрагдах болгонд түүнд нэр өгч, нас өгнө" — нүхтэй заавар: нэр нь ___, нас нь ___ гэсэн, угсралт болгонд шинээр бөглөгддөг хоёр нүх. Тэгээд угсрах хэсэгт нэг онцгой дүр ажилладаг: угсрагч — конвейерийн эхэнд зогсоод, шинэ машин бүрийг хүлээж аваад, нүхэнд бөглөгдөж ирсэн утгуудыг яг энэ машинд хадаж өгдөг ажилтан: "энэ улаан өнгийг энэ машинд, тэр хөхийг тэр машинд" — угсрагчийн ажлын гол чадвар нь "одоо аль машин дээр ажиллаж байгаагаа" мэдэх явдал. Python-ы class-д тэр угсрагч нь init, харин түүний "одоо ажиллаж буй яг энэ машин" гэсэн заалт нь — self юм. Зүйрлэлээ бичиглэл рүү буулгая.
Шинэ файл — nohoi.py:
python
class Nohoi:
def __init__(self, ner, nas):
self.ner = ner
self.nas = nas
minii_nohoi = Nohoi("Банхар", 3)
print(minii_nohoi.ner)
print(minii_nohoi.nas)Үр дүн:
Банхар
3Одоо мөр бүрийг — энэ сургалтын хамгийн удаан задаргаагаар. class Nohoi: — "зураг төслийн цаас эхэлж байна": class бол Python-ы үг, Nohoi бол таны өгсөн загварын нэр — нэг л шинэ дадал: class-ын нэрийг Том үсгээр эхлүүлдэг (snake_case биш!) — Python хориглодоггүй, гэхдээ бүх программист дагадаг хэлэлцээр: нэр Том үсгээр эхэлж байвал "энэ class байна", жижгээр бол "variable/function байна" гэж уншигч нэг харцаар ялгадаг (str, list жижгээр байдаг нь хуучны түүхэн шалтгаантай цөөн үл хамаарах зүйл). Хоёр цэг + шигдсэн бие — class-ын бие: цаасан дээр бичигдэх бүхэн энэ шигдэлтэд.
def init(self, ner, nas): — угсрагчийн заавар. Тийм ээ — class-ын биед def байна: зураг төслийн "угсрах заавар" хэсэг нь function хэлбэрээр бичигддэг. Нэр нь init — доогуур зураас хоёр хоёроороо хоёр талдаа (нийт дөрөв!): initialize ("эхлүүлэх, анхны утгыг өгөх") гэдгийн товчлол — энэ нэрийг та сонгоогүй: Python-ы журамд "class дотор яг ийм нэртэй function байвал түүнийг би object угсрагдах болгонд өөрөө дуудна" гэж заасан тусгай, "гэрээт" нэр: хэв гурилан дээр дарагдах агшинд автоматаар ажилладаг тэр дарагч. Parameter-ууд нь: self (тусгай хэсэгт!), ner, nas — сүүлийн хоёр нь өчигдрийн "нүхнүүд": угсралт болгонд бөглөгдөж ирэх утгууд.
self.ner = ner — угсрагчийн жинхэнэ ажил, өнөөдрийн хамгийн чухал мөр. Уншлага нь: "яг одоо угсрагдаж буй энэ нохойн (self-ийн) ner гэдэг шошгонд — бөглөгдөж ирсэн ner утгыг хадаж өг." Зүүн ба баруун талын ner хоёр өөр юм гэдгийг ажигла: баруун талынх — parameter (угсралтад ирсэн түр утга: угсрагч ажлаа дуусмагц алга болно — function-ий "дотоод ажилтан" дүрэм!), зүүн талынх — self.ner: нохойд өөрт нь наалдсан шошго — угсралт дууссан ч нохойтойгоо хамт үлдэнэ. Ийм "object-д наалдсан variable"-ийг attribute (шинж) гэдэг — string-ийн авдрын эд зүйлс, огнооны .year — таны хуучин танилуудын албан нэр. Хоёр талын нэр ижил (ner = ner) байгаа нь заавал биш — гэхдээ тогтсон, уншихад эвтэй дадал: "ирснийг нь нэрээр нь хадна."
minii_nohoi = Nohoi("Банхар", 3) — конвейер ажиллав! Class-ын нэрийг function шиг дуудахад (нэр + хаалт + argument-ууд) — шинэ object мэндэлдэг: энэ дуудлагын далдад Python шинэ "хоосон нохой" бий болгоод init-ийг өөрөө дуудаж ("Банхар" → ner, 3 → nas — байрлалаар: Бүлэг 8-ын журам!), угсрагч хоёр шошгыг нь хадаж, бэлэн нохой гардуулагдаж minii_nohoi-д хадгалагдана. Сүүлийн хоёр мөр: minii_nohoi.ner — цэгэн хандалт: "энэ нохойн ner шинж" — хаалтгүй (function биш — утга: math.pi, unuudur.year-ийн ах дүү).
Хоёр дахь жишээ: хоёр дахь нохой — нүхний утга. Зураг төслийн жинхэнэ хүчийг эхний хормоос:
python
class Nohoi:
def __init__(self, ner, nas):
self.ner = ner
self.nas = nas
minii = Nohoi("Банхар", 3)
niiziin = Nohoi("Аслан", 7)
print(f"{minii.ner} — {minii.nas} настай")
print(f"{niiziin.ner} — {niiziin.nas} настай")Үр дүн:
Банхар — 3 настай
Аслан — 7 настайНэг цаас — хоёр угсралт — хоёр тусдаа нохой: Банхарын нэрийг уншихад Аслан гарч ирэхгүй — шошго болгон өөрийн эзэнтэй: init-ийн self тэр угсралт болгонд өөр нохойг зааж байсны үр дүн (эхний дуудлагад self = мэндэлж буй Банхар, хоёр дахьд self = Аслан). "Class нэг — object олон" өчигдрийн санаа гурван мөрөнд биежлээ: олон object-ын жинхэнэ баяр дараагийн хичээлүүдэд — өнөөдрийнх нь зөвхөн энэ баталгаа.
Гурав дахь жишээ: attribute бол бүрэн эрхт утга. Шинжүүд жирийн variable шиг бүх эрхтэй:
python
minii = Nohoi("Банхар", 3)
print(f"Банхар хүний насаар {minii.nas * 7} настай")
minii.nas = minii.nas + 1
print(f"Төрсөн өдрийн мэнд! Одоо {minii.nas} настай")
if minii.nas > 5:
print("Ахимаг насны нохой")
else:
print("Залуу нохой")Үр дүн:
Банхар хүний насаар 21 настай
Төрсөн өдрийн мэнд! Одоо 4 настай
Залуу нохойГурван хөдөлгөөн — гурван танил ертөнц: тооцоололд орж (нохойн нэг нас — хүний долоо гэдэг ардын томьёо!), шинэчлэгдэж (minii.nas = minii.nas + 1 — "оньсого мөр" attribute дээр: нохойн шинж угсралтын дараа ч өөрчлөгдөж болно — list шиг "амьд"), нөхцөлд шүүгдэж байна. Attribute гэдэг нь "object-ын дотоод variable" гэдэг тодорхойлолт ажлаараа батлагдлаа: цэгтэй л бичигдэхээс биш зан нь variable.
Дөрөв дэх жишээ: харилцагчийн мэдээлэл — dictionary-тэй зэрэгцүүлэл. "Нэг юмны олон тал" бодлогыг та өмнө нь юугаар шийддэг байсан бэ — dictionary: {"ner": "Бат", "nas": 12}. Одоо хоёр замыг зэрэгцүүлье:
python
class Suragch:
def __init__(self, ner, nas, hot):
self.ner = ner
self.nas = nas
self.hot = hot
bat = Suragch("Бат", 12, "Улаанбаатар")
print(f"{bat.ner}, {bat.nas} настай, {bat.hot} хотоос")Dictionary-гийн suragch["ner"] ба class-ын bat.ner — хоёул "нэрээр хандах": тэгвэл ялгаа нь юу вэ, хэзээ алийг нь вэ? Шударга хариулт: энэ хэмжээний бодлогод — хоёул зөв: dictionary хөнгөн (нэг мөр — бэлэн), class "хатуу гэрээтэй" (Suragch болгон гурван шинжтэй гэдгийг зураг төсөл баталгаажуулдаг — dictionary-д "nas"-аа мартсан ч хэн ч анзаарахгүй, class-д init шаардана: TypeError!). Жинхэнэ давуу нь дараагийн хичээлд ирнэ: class нь шинжээс гадна чадвар (function!) тээж чаддаг — dictionary чаддаггүй цорын ганц, шийдвэрлэх зүйл нь тэр.
Хүсвэл туршаад үзээрэй: Nohoi-доо гурав дахь шинж нэмээрэй — uuld (үүлдэр): init-ийн parameter, self.uuld мөр, дуудлагын гурав дахь argument — гурван газар нэг нэг өөрчлөлт: "нүх нэмэх" бүрэн дасгал. Сонирхвол print(type(minii)) гэж асуугаарай: <class 'main.Nohoi'> — таны өөрийн class type-ийн хариултад str, list-тэй эн зэрэгцэн гарч ирнэ: main гэдэг нь "таны энэ файлд тодорхойлогдсон" гэсэн хаяг — та Python-ы "үйлдвэрлэгчдийн" эгнээнд албан ёсоор орлоо.
Амласан удаан яриа. Self гэж юу вэ — нэг өгүүлбэрт: "яг одоо ажиллаж буй энэ object өөрөө" гэсэн заалт. Будилал нь хоёр асуултаас төрдөг — хоёуланг нь нүүр тулъя. Асуулт нэг: "def init(self, ner, nas) — гурван parameter зарлачихаад Nohoi("Банхар", 3) гэж хоёрхон argument өгдөг нь яав?!" — Бүлэг 8-ын тоо-тааруулах дүрмээр бол TypeError байх ёстой биз дээ! Тайлбар: self-ийн утгыг Python өөрөө өгдөг — Nohoi("Банхар", 3) дуудлагын далдад Python шинэ нохойгоо бүтээгээд түүнийг эхний байранд (self-д) өөрөө хийчихээд, таны хоёр argument-ыг хоёр, гурав дахь байранд оноодог: угсрагч руу "аль машин дээр ажиллахыг" конвейер өөрөө дамжуулдаг — та хэлэх шаардлагагүй. Тиймээс дүрэм: зарлахдаа self-ийг эхэнд нь бичнэ, дуудахдаа тоодоггүй. Асуулт хоёр: "заавал бичих юм бол Python өөрөө "мэдчихэж" болдоггүй юм уу?" — сайн асуулт: зарим хэл яг тэгдэг (далдалдаг). Python "ил байг" гэж зориуд сонгосон: self.ner гэж бичихэд "энэ бол угсралтын түр variable биш — объектод наалдах шинж" гэдэг нь мөр өөрөө хашгирдаг: нэг үгийн "үнээр" хоёр ертөнц (түр ба наалддаг) хэзээ ч холилдохгүй. Тайвшрал-дүрэм хоёр: одоохондоо self-ийг жор болгож хэрэглэ — "class доторх def-ийн эхний parameter нь үргэлж self; object-ын шинжид үргэлж self. угтвартай ханд" — энэ хоёр журмыг дагахад бүх зүйл ажиллана: "мэдрэмж" нь хэрэглээний хэдэн долоо хоногт аяндаа ирдэг гэдгийг сая сая сурагчийн туршлага гэрчилдэг.
Алдаа 1: Self-ээ зарлахаа мартах. Хамгийн түгээмэл нь:
python
class Nohoi:
def __init__(ner, nas):
self.ner = ner
minii = Nohoi("Банхар", 3)Python:
TypeError: Nohoi.__init__() takes 2 positional arguments but 3 were given"2 авдаг байтал 3 өглөө" — гэтэл та хоёрхон л өгсөн шүү дээ?! Гурав дахь нь — Python-ы далдаас хийсэн нохой өөрөө: self-гүй зарлагдсан угсрагч түүнийг авах "суудалгүй" тул тоо халив. Оношийн дүрэм: class доторх TypeError-ын тоонууд "нэгээр зөрж" харагдвал (2 гэтэл 3, 1 гэтэл 2...) — self мартагдсан байх нь бараг гарцаагүй: далд зочны суудлыг нэмээрэй.
Алдаа 2: Биед нь self. угтварыг гээх. Хоёр ертөнцөө хольвол:
python
class Nohoi:
def __init__(self, ner, nas):
ner = ner
self.nas = nas
minii = Nohoi("Банхар", 3)
print(minii.ner)Python:
AttributeError: 'Nohoi' object has no attribute 'ner'"Nohoi object-д ner гэдэг шинж алга" — угсрагч дотор ner = ner гэсэн мөр юу ч хийгээгүй: parameter өөр дээрээ дарагдаад (түр ертөнц дотроо эргэлдээд) угсралт дуусахад алга болжээ — нохойд шошго хадагдаагүй: self.ner = ner байх ёстой байсан. AttributeError бол энэ бүлгийн "KeyError" нь: "тийм шинж энэ object-д алга" — шалтгаан нь бараг үргэлж угсрагч дотор: аль self. нь мартагдсаныг init-ээ мөрөөр нь шалгаж ол.
Алдаа 3: Object угсралгүй class-аас шууд шинж нэхэх. Цаас ба машинаа андуурвал:
python
class Nohoi:
def __init__(self, ner, nas):
self.ner = ner
self.nas = nas
print(Nohoi.ner)Python:
AttributeError: type object 'Nohoi' has no attribute 'ner'Мөн AttributeError — гэхдээ мэдэгдлийг нь ойрхон уншаарай: type object 'Nohoi' — "Nohoi гэдэг зураг төсөлд ner гэж алга": зөв шүү дээ — нэр бол угсрагдсан машин болгоны өөрийн зүйл: цаасан дээр "нэртэй байна" гэсэн заавар л бий — нэр өөрөө байхгүй: "зураг төслийн машинаар давхиж болохгүй" гэдэг өчигдрийн санаа алдааны мэдэгдэл болж ирлээ. Засвар: эхлээд угсар — nohoi = Nohoi("Банхар", 3) — тэгээд nohoi.ner. Оношийн түлхүүр үг: мэдэгдэлд type object гэж орсон бол "object угсрахаа мартаад class-аас шууд нэхжээ" гэсэн онош.
class Nohoi: — зураг төслийн эхлэл (нэр нь Том үсгээр — хэлэлцээр); биед нь def init(self, ...): — угсрагч: object мэндлэх болгонд Python өөрөө дууддаг "гэрээт" нэр.
self.ner = ner — угсралтын гол мөр: түр parameter-ийн утгыг объектод наалддаг шинж (attribute) болгож хадна; шинж нь жирийн утга: тооцоолж, шинэчилж, шүүж болно.
Nohoi("Банхар", 3) — class-ыг дуудахад object мэндэлж гардуулагдана; шинжид нь цэгээр (хаалтгүй) ханд: minii.ner.
Self = "яг энэ object": зарлахдаа эхний parameter, дуудахдаа тоохгүй (Python өөрөө өгнө); биед шинжид үргэлж self. угтвар — будилвал зөв замдаа: жор + хэрэглээ = аяндаа ирэх мэдрэмж.
Гурван онош: тоо "нэгээр зөрсөн" TypeError — self мартагдав; object-ын AttributeError — угсрагчид self. гээгдэв; type object-ын AttributeError — угсралгүй class-аас нэхэв.
Дараагийн хичээлд зураг төсөл маань чадвартай болно: method — class доторх function: нохой маань хуцаж сурна! Тэгээд Бүлэг 9-ийн хамгийн том амлалт эцсийн эзнээ олно: ner.upper() гэж бичих болгондоо та юу хийж байсан бэ — string class-ын method дуудаж байжээ: авдрын нууц бүрэн тайлагдана.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.