Ишлэл:
yield гэж ер нь яг юу байнаа? энийг нэг л ойлгодоггүй ээ
За, тэгэхээр ийм байна. Yield-г ойлгохын тулд эхлээд generator-ыг ойлгох хэрэгтэй. Generator-ыг ойлгохын өмнө iterator-ыг ойлгох хэрэгтэй юм. Эдгээрийг жишээн дээр тайлбарлая. Нэр томъёог орчуулж хэрэглэх гэж оролдлоо, ойлгоорой.
Iterator (
давтуур) бол ямар нэг өгөгдлийн цуваа буюу
iterable (
давтуулагч) -ийн гишүүн бүрийг нэг нэгээр уншдаг зүйл юм. Жишээ нь list (цуваа) бол давтуур:
Код:
>>> sondgoi = [1, 3, 5]
>>> for n in sondgoi:
... print(n)
...
1
3
5
Цуваанаас гадна файл, тэмдэгт мөр гээд олон төрлийн зүйл давтуулагч байдаг.
List comprehension-оор мөн давтуур үүсгэж болно. Энэ бол цуваа үүсгэх хураангуй бичиглэл юм. Жишээ нь:
Код:
>>> sondgoi = [n for n in range(6) if n%2]
>>> for n in sondgoi:
... print(n)
...
1
3
5
Өмнөх жишээтэй үр дүн адил боловч цувааг үүсгэхдээ давталт, функц, нөхцөл шалгалт ашиглаж байна.
За
давтуур гэж зүйл бүрийг нь ээлжлэн уншиж болдог давтуулагч байдаг юм байна. Тэгвэл
generator (
үүсгүүр) гэж юу вэ? Энгийн давтуурыг нэг удаа бүтээгээд хэдэн ч удаа ашиглаж болно (Цувааг хувьсагчид оноогоод хэдэн ч удаа давтаж болдог, г.м.). Гэвч өгөгдлийг санах ойд хадгалах хэрэгтэй болдог. Маш олон гишүүн өгөгдөл хэрэглэх болоход давтуурын энэ чанар саад болох болно.
Харин үүсгүүр ашиглан үүсгэсэн давтуулагчийг санах ойд хадгалалгүйгээр, гишүүн утга бүрийг нэг л удаа уншаад өнгөрдөг. Түр зуурын давтуулагч гэж хэлж болно. Санах ойд хадгалдаггүй, түр зуурын чанар нь
төгсөшгүй давтуулагч бүтээх боломжийг олгодог
Код:
>>> sondgoi = (n for n in range(6) if n%2)
>>> for n in sondgoi:
... print(n)
...
1
3
5
>>> for n in sondgoi:
... print(n)
...
Өмнөх жишээтэй адилхан юм шиг байна уу? List comprehension-ын хаалт дугуй болж өөрчлөгдсөнийг анзаараарай. Ингэвэл давтуур биш үүсгүүр үүсдэг. sondgoi хувьсагчаа хоёр дахь удаа давтая гэвч болохгүй. Үүсгүүр нэг л удаа ашиглагдана.
Yield бол, фүнкцийг төгсгөж хариу буцаадаг
return-ы оронд хэрэглэдэг түлхүүр үг юм.
Өмнөх жишээнүүдээ өргөтгөн
бүх 
сондгой тоог гаргадаг үүсгүүр бичье:
Код:
# sondgoi.py
import itertools
def sondgoi():
for n in itertools.count(1):
if n%2:
yield n
itertools.count фүнкц өгөгдсөн тооноос эхлэн ихэсгэн тоолдог.
Бүх сондгой тооны үүсгүүр бэлэн боллоо. Гэхдээ нэг л юм дутаж байна. Ямар нэг зогсох цэг заахгүй бол төгсөхгүй үргэлжлэх нь байна
Код:
# sondgoi.py
import itertools
def sondgoi(m):
for n in itertools.count(1):
if n%2:
yield n
if n is m:
break
for n in sondgoi(20):
print(n)
Энд нэг санах зүйл бол үүсгүүр фүнкцийг ажиллуулахад
хариу буцдаггүй, харин үүсгүүр бий болдог. Харин үүсгүүр дээр давтах болгонд фүнкц ажиллаж утга буцаадаг.
Ойлгоход эхэнд ярвигтай байж магад. Өөрөө туршиц код бичиж үзээд байвал аяндаа толгойд суух вий. Амжилт хүсье.
Жич: Мөн мэдээж гүүгэлдэхээ мартаж болохгүй:
? python yield