Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

เมื่อไหร่ควรใช้ yield แทน return ใน Python

สรุปสั้นๆ: return จบการทำงานฟังก์ชันทันที ข้อความหลัง return ไม่รัน yield หยุดชั่วคราว (Pause) คืนค่า และResume ได้ภายหลัง

Yield - Generator Function

ใช้ yield ในฟังก์ชัน → ฟังก์ชันกลายเป็น Generator Function ใช้ใน Loop ได้

def gen_func():
    yield 1
    yield 2
    yield 3

for num in gen_func():
    print(num * num)

ผลลัพธ์

1
4
9

Loop เรียก Generator → รันจนถึง yield → คืนค่า → Pause → Loop รอบถัดไป Resume หลัง yield จนจบฟังก์ชันหรือเจอ return

Return - Regular Function

  • หยุดการทำงานฟังก์ชันทันที คืนค่า (ถ้ามี) ให้ Caller
  • ฟังก์ชันที่มี return (ไม่มี yield) ไม่สามารถใช้ใน Loop ได้แบบ Generator
  • เรียกฟังก์ชันเดิมอีกครั้ง → เริ่มต้นจาก ראש ฟังก์ชันใหม่ทั้งหมด

เมื่อไหร่ใช้ yield?

  • ต้องการ Iterate ผลลัพธ์ทีละชิ้น (Lazy Evaluation)
  • Sequence ใหญ่หรือ Infinite ไม่อยากเก็บทั้งหมดใน Memory
  • Stream Processing, Large Files, Infinite Sequences

เมื่อไหร่ใช้ return?

  • คำนวณเสร็จแล้วคืนผลลัพธ์ครั้งเดียว
  • ผลลัพธ์เล็ก ใช้ Memory น้อย
  • ต้องการคืนค่า Structured Data (Dict, Object) ครั้งเดียว

ตัวอย่าง: Infinite Square Generator

def squares():
    i = 1
    while True:
        yield i * i
        i += 1

# ใช้งาน: หยุดเองเมื่อพอ
for num in squares():
    if num > 100:
        break
    print(num)

ผลลัพธ์

1
4
9
16
25
36
49
64
81
100

ข้อควรระวัง: yield ใน try...finally

yield ใน try Clause ของ try...finally อาจทำให้ finally ไม่รัน เพราะ Generator อาจไม่ถูก Resume อีก

# ระวังการใช้งานแบบนี้
def risky():
    try:
        yield 1
        yield 2
    finally:
        print("Cleanup")  # อาจไม่รันถ้า Generator ไม่ถูก Exhaust

g = risky()
print(next(g))  # 1
# หากไม่เรียก next(g) อีก finally จะไม่รัน

สรุปเปรียบเทียบ

Featurereturnyield
ExecutionRun to completionPause/Resume
Return TypeSingle ValueGenerator Object
MemoryStore all resultsLazy, One at a time
ReusabilityNew call = New executionGenerator exhausted after one iteration
Use CaseCompute & ReturnStream, Large/Infinite Sequences