Ачааллж байна...
Курс 1-д та function бичиж сурсан. Тэр үед та үүнийг жор гэж зүйрлэж байсныг санаж байгаа байх: жор нь орц (parameter) хүлээж авдаг, дотроо зааврын дагуу ажилладаг, эцэст нь бэлэн хоол (return утга) буцаадаг. Тэр зүйрлэл хэвээрээ, зөвхөн бид одоо жорыг илүү уян хатан болгох аргуудыг үзэх гэж байна.
Курс 1-ийн function-ууд нэг хатуу дүрэмтэй байсан: параметр бүрд заавал утга дамжуулах ёстой. Хэрэв функц гурван параметртэй бол та түүнийг дуудахдаа гурван утга өгөх ёстой, эс тэгвээс алдаа гарна. Энэ дүрэм ойлгомжтой ч, практикт хэт хатуу байдаг. Учир нь бодит амьдрал дээр параметрүүдийн зарим нь "ихэнхдээ ижилхэн байдаг, гэхдээ заримдаа өөрчлөгддөг" гэсэн шинжтэй байдаг.
Жишээ нь мэндчилэх функц бичье гэж бодъё. Ихэнх тохиолдолд та "Сайн байна уу" гэж мэндчилнэ, гэхдээ заримдаа "Өглөөний мэнд" гэж хэлмээр байна. Хэрэв мэндчилгээг заавал дамжуулах параметр болговол та түүнийг ХЭДЭН ЗУУН удаа "Сайн байна уу" гэж давтан бичих болно — зөвхөн хааяа өөрчлөгддөг учраас. Энэ асуудлыг default утга (анхдагч утга) шийддэг.
Кофены дэлгүүрт орлоо гэж төсөөлье. Та "нэг капучино" гэж захиалахад зөөгч танаас "хэдэн градус халуун байлгах вэ? Ямар аяганд? Сүү хэдэн хувь өөх тостой байх вэ?" гэж асуухгүй. Тэр зүгээр л стандарт капучино авчирна. Учир нь дэлгүүрт эдгээр асуултуудын АНХДАГЧ хариулт байдаг: халуун, дунд аяга, ердийн сүү.
Гэхдээ хэрэв та тусгайлан хүсвэл өөрчилж болно: "нэг капучино, гэхдээ том аяганд." Тэгэхэд зөөгч зөвхөн тэр нэг зүйлийг л өөрчилнө, үлдсэн нь анхдагчаараа хэвээр байна.
Default parameter бол яг энэ. Функц нь "хэрэв та юу ч хэлэхгүй бол би үүнийг ашиглана" гэсэн урьдчилсан хариулттай байна. Дуудагч хүн шаардлагатай үедээ л тэр хариултыг дарж бичнэ. Ингэснээр энгийн тохиолдол богино, ховор тохиолдол боломжтой хэвээр үлддэг.
Эхлээд default-гүй функц бичье — Курс 1-ийн хэв маягаар.
python
def mendchilekh(ner, mendchilgee):
print(f"{mendchilgee}, {ner}!")
mendchilekh("Болд", "Сайн байна уу")
mendchilekh("Сараа", "Сайн байна уу")
mendchilekh("Төмөр", "Сайн байна уу")
mendchilekh("Цэцэг", "Өглөөний мэнд")Үр дүн:
Сайн байна уу, Болд!
Сайн байна уу, Сараа!
Сайн байна уу, Төмөр!
Өглөөний мэнд, Цэцэг!Код зөв ажиллаж байна. Гэхдээ анзаараарай: "Сайн байна уу" гэсэн string гурван удаа давтагдсан. Хэрэв энэ функцийг зуун газарт дуудвал тэр string ерэн есөн удаа давтагдана. Энэ нь зөвхөн урт байгаа юм биш — хэрэв та ирээдүйд стандарт мэндчилгээгээ өөрчлөхийг хүсвэл ерэн есөн газар засах хэрэгтэй болно, тэдгээрийн нэгийг мартах магадлал өндөр.
python
def mendchilekh(ner, mendchilgee="Сайн байна уу"):
print(f"{mendchilgee}, {ner}!")
mendchilekh("Болд")
mendchilekh("Сараа")
mendchilekh("Төмөр")
mendchilekh("Цэцэг", "Өглөөний мэнд")Үр дүн яг ижил:
Сайн байна уу, Болд!
Сайн байна уу, Сараа!
Сайн байна уу, Төмөр!
Өглөөний мэнд, Цэцэг!Эхний мөрийг задалъя. def mendchilekh(ner, mendchilgee="Сайн байна уу"): гэсэн бичлэгт хоёр параметр байна. ner нь ердийн параметр — түүнд default утга байхгүй тул дуудахдаа ЗААВАЛ утга өгөх ёстой. mendchilgee нь тэнцүү тэмдэгтэй, дараа нь утгатай — энэ бол default утга.
Default утга нь юу гэсэн үг вэ? "Хэрэв дуудагч энэ параметрт утга өгөөгүй бол, "Сайн байна уу" гэсэн утгыг ашигла" гэсэн үг. Тэгэхээр mendchilekh("Болд") гэж дуудахад Python нь ner -д "Болд" -ыг олгож, mendchilgee -д default утгыг олгож ажиллана.
Харин mendchilekh("Цэцэг", "Өглөөний мэнд") гэж дуудахад дуудагч хоёр дахь утгыг өгсөн тул default нь ашиглагдахгүй, өгсөн утга нь давамгайлна.
Одоо давхардал арилсныг анзаараарай. Мөн хэрэв та ирээдүйд стандарт мэндчилгээгээ өөрчлөхийг хүсвэл ГАНЦХАН газар — функцийн тодорхойлолт дээр — засахад л хангалттай. Энэ бол default утгын жинхэнэ ач холбогдол: тохиргоог нэг л газарт төвлөрүүлдэг.
Python-д нэг хатуу дүрэм байдаг: default утгатай параметрүүд нь default утгагүй параметрүүдийн АРД байрлах ёстой.
Хэрэв энэ дүрмийг зөрчвөл:
python
def mendchilekh(mendchilgee="Сайн байна уу", ner):
print(f"{mendchilgee}, {ner}!") File "main.py", line 1
def mendchilekh(mendchilgee="Сайн байна уу", ner):
^^^
SyntaxError: parameter without a default follows parameter with a defaultSyntaxError: parameter without a default follows parameter with a default гэдэг нь "default утгагүй параметр нь default утгатай параметрийн ард орсон байна" гэсэн үг. Python үүнийг зөвшөөрөхгүй, программ огт эхлэхгүй.
Яагаад ийм дүрэм байна вэ? Логикоо бодоод үзье. Хэрэв дээрх функц зөвшөөрөгдсөн байсан бол mendchilekh("Болд") гэж дуудахад Python юу гэж бодох вэ? "Болд" гэдэг нь mendchilgee -д зориулагдсан уу, эсвэл ner -д зориулагдсан уу? Хариулт байхгүй — тодорхойгүй байдал. Тиймээс Python энэ тодорхойгүй байдал үүсэх боломжийг эхнээс нь хааж, дүрэм болгосон.
Санах хялбар арга: заавал байх ёстой зүйлс эхэнд, сонголттой зүйлс араас.
Функц нэгээс олон default параметртэй байж болно.
python
def barааnii_medeelel(ner, une=0, too=1, valuta="MNT"):
niit = une * too
print(f"{ner}: {too} ширхэг x {une} = {niit} {valuta}")
barааnii_medeelel("Ном")
barааnii_medeelel("Ном", 15000)
barааnii_medeelel("Ном", 15000, 3)
barааnii_medeelel("Ном", 15000, 3, "USD")Үр дүн:
Ном: 1 ширхэг x 0 = 0 MNT
Ном: 1 ширхэг x 15000 = 15000 MNT
Ном: 3 ширхэг x 15000 = 45000 MNT
Ном: 3 ширхэг x 15000 = 45000 USDЭнэ жишээ нь default утгын хүчийг тод харуулж байна. Нэг л функц дөрвөн өөр аргаар дуудагдаж, тус бүрдээ зөв ажиллаж байна. Дуудагч зөвхөн өөрт нь хэрэгтэй хэрийг л бичиж, үлдсэнийг нь функцэд даатгаж байна.
Гэхдээ энд нэг хязгаарлалт нуугдаж байна. Хэрэв та зөвхөн valuta-г өөрчилж, une ба too-г default-аар нь үлдээмээр бол яах вэ? Одоогийн мэдлэгээр та үүнийг хийж чадахгүй — учир нь та утгуудыг ДАРААЛЛААР нь дамжуулж байгаа тул дөрөв дэх утгад хүрэхийн тулд эхний гурвыг нь заавал бичих хэрэгтэй болно:
python
barааnii_medeelel("Ном", 0, 1, "USD")Энэ ажиллана, гэхдээ 0 ба 1 гэсэн утгуудыг зөвхөн "цаад талд нь хүрэхийн тулд" бичиж байгаа нь эвгүй. Энэ асуудлыг дараагийн хичээлд үзэх keyword argument цэвэрхэн шийднэ. Тэнд та ингэж бичиж чадна:
python
barааnii_medeelel("Ном", valuta="USD")Одоохондоо энэ хязгаарлалтыг мэдэж, дараагийн хичээлийг хүлээж байгаарай.
Заримдаа танд "утга байхгүй" гэсэн default хэрэгтэй болдог. Тэр үед Курс 1-ээс танил None-ыг ашиглана.
python
def hun_burtgekh(ner, utas=None):
print(f"Нэр: {ner}")
if utas is None:
print("Утас: бүртгэгдээгүй")
else:
print(f"Утас: {utas}")
hun_burtgekh("Болд")
hun_burtgekh("Сараа", "99112233")Үр дүн:
Нэр: Болд
Утас: бүртгэгдээгүй
Нэр: Сараа
Утас: 99112233Энд None нь "энэ утга огт өгөгдөөгүй" гэсэн санааг илэрхийлж байна. Функц дотор бид if utas is None: гэж шалгаж, өгөгдсөн эсэхээс хамааран өөр өөр зан төлөв харуулж байна.
Анзаараарай, is None гэж бичсэн, == None гэж БИЧЭЭГҮЙ. Python-д None-ыг шалгах зөв арга нь is юм. Хоёулаа ихэвчлэн ижил ажилладаг ч is нь илүү зөв, илүү хурдан, мэргэжлийн стандарт бичлэг. Курс 1-д энэ талаар товч дурдсан байх, одоо түүнийг дүрэм болгож санаж яваарай.
Яагаад хоосон string ("") эсвэл тэг (0) ашиглахгүй байна вэ? Учир нь тэдгээр нь БОДИТ утга байж болно. Жишээ нь une=0 гэсэн default нь ойлгомжтой (үнэгүй бараа), гэхдээ хэрэв та "үнэ огт өгөгдөөгүй" гэсэн санааг илэрхийлэхийг хүсвэл 0 тохирохгүй — учир нь 0 бол жинхэнэ үнэ байж болно. None бол цорын ганц "юу ч биш" гэдгийг тодорхой илэрхийлдэг утга юм.
Курс 1-ийн хийх ажлын жагсаалтын төслийг санаж байна уу? Тэнд ажил нэмэх функц ийм байсан байх:
python
def ajil_nemekh(jagsaalt, ner, chukhal):
ajil = {"ner": ner, "chukhal": chukhal, "duussan": False}
jagsaalt.append(ajil)
return jagsaaltПрактикт ихэнх ажил чухал БИШ байдаг, чухал нь ховор. Тиймээс default утга тавьвал:
python
def ajil_nemekh(jagsaalt, ner, chukhal=False, duussan=False):
ajil = {"ner": ner, "chukhal": chukhal, "duussan": duussan}
jagsaalt.append(ajil)
return jagsaalt
ajluud = []
ajil_nemekh(ajluud, "Сүү авах")
ajil_nemekh(ajluud, "Тайлан бичих", True)
for ajil in ajluud:
tsagt = "ЧУХАЛ" if ajil["chukhal"] else "энгийн"
print(f"{ajil['ner']} ({tsagt})")Үр дүн:
Сүү авах (энгийн)
Тайлан бичих (ЧУХАЛ)Ердийн ажил нэмэхэд одоо гурав дахь аргумент бичих шаардлагагүй боллоо. Дашрамд, tsagt = "ЧУХАЛ" if ajil["chukhal"] else "энгийн" гэсэн мөр нь өмнөх хичээлээс танил ternary юм — Бүлэг 2-ын мэдлэг ажилд орж эхэллээ.
Одоо би танд Python-ы хамгийн алдартай, хамгийн олон хүнийг хуурсан урхийг харуулна. Энэ бол чухал сэдэв тул анхааралтай уншаарай — гэхдээ айх хэрэггүй, засах нь маш амархан.
Дараах кодыг хараарай:
python
def ajil_nemekh(ner, jagsaalt=[]):
jagsaalt.append(ner)
return jagsaalt
negdugeer = ajil_nemekh("Сүү авах")
print(negdugeer)
hoyordugaar = ajil_nemekh("Тайлан бичих")
print(hoyordugaar)Логикоор бол юу гарах ёстой вэ? Функц бүрд шинэ хоосон жагсаалт үүсэж, дараа нь нэг ажил нэмэгдэх ёстой. Тэгэхээр:
['Сүү авах']
['Тайлан бичих']Гэвч бодит үр дүн:
['Сүү авах']
['Сүү авах', 'Тайлан бичих']Хоёр дахь дуудалт нь ХООСОН жагсаалт биш, эхний дуудалтын үлдэгдэл дээр нэмсэн байна. Алдааны мессеж алга, программ унасангүй — зүгээр л буруу ажиллаж байна. Ийм алдаа хамгийн аюултай нь.
Яагаад ингэж байна вэ? Учир нь default утга нь функц ДУУДАГДАХ бүрд шинээр үүсдэггүй. Тэр нь функц ТОДОРХОЙЛОГДОХ үед — өөрөөр хэлбэл def мөр анх ажиллах үед — ГАНЦ УДАА үүсдэг. Тэгэхээр jagsaalt=[] гэсэн хоосон жагсаалт нь программын эхэнд нэг л удаа үүссэн бөгөөд функц түүнийг ХУВААЛЦАЖ ашиглаж байна. Нэг дуудалт түүнд нэмэхэд, тэр нэмэлт нь дараагийн дуудалтад ч үлдэнэ.
Курс 1-ээс list нь өөрчлөгддөг (mutable) гэдгийг санаж байгаа байх. Яг тэр өөрчлөгдөх чанар нь энд урхи болж байна. Хэрэв default нь string, тоо, эсвэл None байсан бол ямар ч асуудал үүсэхгүй, учир нь тэдгээр нь өөрчлөгддөггүй (immutable).
Засвар нь маш энгийн: default-ыг None болго, дараа нь функц дотор шинэ жагсаалт үүсгэ.
python
def ajil_nemekh(ner, jagsaalt=None):
if jagsaalt is None:
jagsaalt = []
jagsaalt.append(ner)
return jagsaalt
negdugeer = ajil_nemekh("Сүү авах")
print(negdugeer)
hoyordugaar = ajil_nemekh("Тайлан бичих")
print(hoyordugaar)Одоо зөв үр дүн:
['Сүү авах']
['Тайлан бичих']Яагаад ажиллаж байна вэ? None нь өөрчлөгддөггүй тул хуваалцах асуудал үүсэхгүй. Функц дуудагдах бүрд if jagsaalt is None: шалгалт ажиллаж, ШИНЭ хоосон жагсаалт үүсгэнэ. Тэр шинэ жагсаалт нь тухайн дуудалтад л хамаарна.
Санах дүрэм: Default утга нь ХЭЗЭЭ Ч list, dictionary, set байж болохгүй. Тэдгээрийн оронд None тавьж, функц дотроо үүсгэ.
Энэ дүрмийг та эхэндээ механикаар л дагаж болно — цаад шалтгааныг нь бүрэн ойлгохгүй байсан ч гэсэн зөв код бичих болно. Ойлголт нь дадлагатай хамт ирнэ.
Хэрэв сонирхвол: mutable default trap-ын кодыг өөрөө бичиж, гурван удаа дуудаад юу болохыг өөрийн нүдээр хараарай. Дараа нь None -оор засаад, ялгааг мэдрээрэй. Ном унших нь нэг хэрэг, өөрийн терминал дээр буруу үр дүн гарахыг харах нь тэс өөр хэрэг — тэр дурсамж танд удаан үлдэнэ.
Мөн хүсвэл: Курс 1-д бичсэн ямар нэг функцээ нээгээд, параметрүүдийнх нь дотроос "ихэнхдээ ижилхэн утгатай дамжуулагддаг" нэгийг нь хайж үзээрэй. Түүнд default утга өгөөд, дуудалтуудаа хялбарчилж үзээрэй.
1. Default-гүй параметрийг ард нь тавих
SyntaxError: parameter without a default follows parameter with a defaultДээр дэлгэрэнгүй үзсэн. Заавал байх параметрүүд эхэнд, default-тай нь араас.
2. Mutable default (list, dict)
Алдааны мессеж ГАРАХГҮЙ — энэ л аюул нь. Программ чимээгүйхэн буруу ажиллана. Засвар: None ашигла.
3. Default-ыг өөр параметрээс тооцоолох гэж оролдох
python
def zarlaga(une, tatvar=une * 0.1):
return une + tatvarTraceback (most recent call last):
File "main.py", line 1, in <module>
def zarlaga(une, tatvar=une * 0.1):
NameError: name 'une' is not definedNameError: name 'une' is not defined гэдэг нь "une нэртэй зүйл олдсонгүй" гэсэн үг. Шалтгаан нь: default утгууд нь def мөр ажиллах үед тооцоологддог, гэтэл тэр мөчид une хараахан оршин байхгүй — тэр зөвхөн функц ДУУДАГДАХ үед л утга авна. Засвар: None ашиглаад функц дотор тооцоол.
python
def zarlaga(une, tatvar=None):
if tatvar is None:
tatvar = une * 0.1
return une + tatvar4. Хэт олон параметр өгсөн
python
def mendchilekh(ner, mendchilgee="Сайн байна уу"):
print(f"{mendchilgee}, {ner}!")
mendchilekh("Болд", "Сайн уу", "нэмэлт")Traceback (most recent call last):
File "main.py", line 5, in <module>
mendchilekh("Болд", "Сайн уу", "нэмэлт")
TypeError: mendchilekh() takes from 1 to 2 positional arguments but 3 were giventakes from 1 to 2 positional arguments but 3 were given гэдэг нь "энэ функц нэгээс хоёр аргумент авдаг ч гурвыг өглөө" гэсэн үг. Анзаараарай, мессеж нь "1-ээс 2" гэж хэлж байна — default утгын ачаар доод хязгаар нь 1 болсон. Энэ бол алдааны мессежийг сайн уншвал функцийн бүтцийг нь ойлгож болдгийн жишээ.
Default utga нь параметрийн "хэрэв юу ч өгөөгүй бол ашиглах" урьдчилсан хариулт: def f(ner, mendchilgee="Сайн байна уу").
Тохиргоог нэг газарт төвлөрүүлдэг — давхардлыг арилгаж, өөрчлөхөд хялбар болгодог.
Хатуу дүрэм: default-гүй параметрүүд эхэнд, default-тай нь араас. Эс тэгвээс SyntaxError.
"Утга огт өгөгдөөгүй" гэдгийг илэрхийлэхэд None ашигла; is None гэж шалга (== None биш).
Mutable default trap: default нь list, dict, set БАЙЖ БОЛОХГҮЙ. Тэд функц тодорхойлогдох үед ганц удаа үүсэж, дуудалтууд хооронд хуваалцагддаг. Оронд нь None тавьж, функц дотроо үүсгэ.
Default утгууд нь def мөр ажиллах үед тооцоологддог — тиймээс тэдгээрт өөр параметрийг ашиглаж болохгүй.
Дараагийн хичээлд бид энэ хичээлд гарсан нэг хязгаарлалтыг шийднэ: аргументуудыг дарааллаар нь биш, НЭРЭЭР нь дамжуулах арга. Түүнийг keyword argument гэж нэрлэдэг бөгөөд тэр нь barааnii_medeelel("Ном", valuta="USD") гэж бичих боломжийг өгнө. Мөн энэ нь framework-ийн код яагаад name=value хэлбэрээр дүүрэн байдгийн шалтгаан юм.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.