By Arnon Puitrakul - 17 กุมภาพันธ์ 2022
เรื่องที่น่าสนใจ และ หลาย ๆ คนมองข้ามไปคือเรื่องพื้นฐานมาก ๆ อย่าง For-Loop หรือ Loop อื่น ๆ อย่าง While Loop เราก็ใช้กันบ่อยนะ ใช้กันแทบจะทุกโปรแกรมเลย แต่เราเคยสงสัยกันมั้ยว่า เบื้องหลังของมัน มันทำงานยังไงถึงออกมาให้เราใช้งานได้แบบนี้ โดยของที่ถือว่าเป็น Foundation ในเรื่องนี้คือ Iterable และ Iterator
Iterable ถ้าจะให้อธิบายง่าย ๆ คือ Object ที่มีความสามารถในการ Iterate หรือง่ายกว่านั้นอีก คือมันสามารถ Return สมาชิกของมันในแต่ละรอบได้ ถ้าเราเขียน Python มา พวกนี้มันก็คืออะไรก็ตามที่เราสามารถ Loop ใส่มันได้นั่นเอง
>>> iter("Hello World")
<str_iterator object at 0x102b09e20>
>>> iter([1,2,3,4])
<list_iterator object at 0x102b26070>
>>> iter(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
ตัวอย่างเช่น String ใน Python มันก็จะประกอบด้วย Character หลาย ๆ ตัวต่อกัน การ Iterate ก็คือการที่มันพ่น Character ที่อยู่ใน String ออกมาในแต่ละรอบนั่นเอง ซึ่งถ้า Object ไหนที่เป็น Iterable Object เราสามารถยัดมันใส่ Function ที่ชื่อว่า iter() ได้ จากตัวอย่างสุดท้ายเราจะเห็นว่า มันไม่สามารถ Iterate ได้ เพราะ Integer ไม่ใช่ Iterable Object นั่นเอง
>>> hello_iter = iter("Hello World")
>>> next(hello_iter)
'H'
>>> next(hello_iter)
'e'
ณ ตอนนี้เรามี Object ที่สามารถ Iterate ได้แล้ว ก็คือ Iterable แล้วถามว่า ใครจะที่จะเป็นคนไล่รันเอาค่าสมาชิกออกมา สิ่งนั้นก็คือ Iterator มองภาพง่าย ๆ ว่ามันเป็นเครื่องจักรที่เอาค่าออกมา จากใน iter() ตัวมันเอง มันก็ทำอะไรไม่ได้ แต่มันจะเริ่มโยนสมาชิกออกมาก็ต่อเมื่อเราเรียกอีกคำสั่งนึง นั่นคือ next()
>>> next(hello_iter)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
แต่แน่นอนว่าจำนวนสมาชิกมันไม่ได้มีไม่อั้น มันมีจำกัด อย่างใน String "Hello World" ก็มีสมาชิก 11 ตัวด้วยกัน เมื่อเราเรียก next() ไปเรื่อย ๆ จนถึงครั้งที่ 12 ตัว Python จะดัน Exception ออกมาว่าเป็น StopIteration Exception ขึ้นมา ซึ่งเราสามารถเอา Try...Except มาจับได้
>>> list_iter = iter([1,2])
>>> next(list_iter)
1
>>> next(hello_iter)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
เมื่อเรารัน Iterator เพิ่มเข้าไปอีกหนึ่งตัวในโปรแกรม เราจะเห็นว่า Iterator ก็ยังทำงานได้อย่างถูกต้อง โดยเอาอันสมาชิกตัวแรกออกมา และเมื่อเราเรียก Iterator ตัวก่อนหน้าที่มันเรียกจนหมดแล้ว มันก็ยังคงคืน Exception กลับมาเหมือนเดิม จากการทดลองนี้ เราได้ข้อสังเกตว่าแต่ละ Iterator มันก็จะมีการจัดการ State ของใครของมัน ไม่เกี่ยวกับส่วนกลางใด ๆ ทั้งสิ้น
เรื่องนี้เราสามารถอธิบายได้จากวิธีการสร้าง Iterable บน Class โดยที่ Class นั้น ๆ จะเป็น Iterable ได้ มันจะต้องมีการ Implement Dunder Method ที่ชื่อว่า __iter__ ลงไปด้วย แล้วเมื่อเราสร้างออกมาเป็น Object ไม่ว่าเราจะสร้างออกมากี่อัน แต่จะตัว มันก็จะมีการจัดการ State ในตัวของมันเอง เหมือนกับที่เราสามารถใส่ค่าใน Attribute ที่ไม่เหมือนกันได้นั่นเอง
หลังจากเราเข้าใจ Concept ของคำว่า Iterable และ Iterator แล้ว เรามาดูคำตอบกันว่าจริง ๆ แล้ว For-Loop เขาทำงานยังไงใน Python เราอยากให้ลองเอาสิ่งที่เราเล่าเมื่อกี้มาคิดดูก่อนว่า มันน่าจะทำอย่างไร ถึงออกมาเป็น For-Loop ได้...... โอเค เฉลย
ขั้นตอนของมันจริง ๆ คือ มันจะแปลง Iterable ให้เป็น Iterator ก่อนผ่านคำสั่ง iter() จากนั้น มันก็จะเรียก next() ของ Iterator ที่สร้างเอาไว้ ทำแบบนี้ไปเรื่อย ๆ จนกว่าจะได้ StopIteration ออกมา มันก็จะออกจาก Loop นั่นเอง อื้อ แค่นั้นเลย....
วันนี้เรามาเล่าในหลังม่านการทำงานของ For-Loop ทั้งหลาย ซึ่งมันใช้ 2 ส่วนในการทำให้มันเกิดขึ้นได้คือ Iterable และ Iterator ทำงานเข้าด้วยกัน โดยที่ทั้ง 2 อย่างนี้มีความแตกต่างกัน คือ Iterable คือ Object ที่สามารถ Iterate ได้ ส่วน Iterator เป็นเหมือนเครื่องจักรในการพ่นค่าสมาชิกใน Iterable ออกมานั่นเอง เอาจริง ๆ แล้ว หลาย ๆ คนอาจจะมองว่ามันเป็นเรื่องที่ เออ รู้ทำไมอะ เราว่ามันทำให้เออรู้สึกว่า Python มันเป็นภาษาที่แปลกดีนะ มันใช้วิธีแบบนี้เพื่อให้มันเข้าใจได้ง่าย และ นำไปใช้ได้ง่าย
เราเป็นคนที่อ่านกับซื้อหนังสือเยอะมาก ปัญหานึงที่ประสบมาหลายรอบและน่าหงุดหงิดมาก ๆ คือ ซื้อหนังสือซ้ำเจ้าค่ะ ทำให้เราจะต้องมีระบบง่าย ๆ สักตัวในการจัดการ วันนี้เลยจะมาเล่าวิธีการที่เราใช้ Obsidian ในการจัดการหนังสือที่เรามีกัน...
หากเราเรียนลงลึกไปในภาษาใหม่ ๆ อย่าง Python และ Java โดยเฉพาะในเรื่องของการจัดการ Memory ว่าเขาใช้ Garbage Collection นะ ว่าแต่มันทำงานยังไง วันนี้เราจะมาเล่าให้อ่านกันว่า จริง ๆ แล้วมันทำงานอย่างไร และมันมีเคสใดที่อาจจะหลุดจนเราต้องเข้ามาจัดการเองบ้าง...
ก่อนหน้านี้เราเปลี่ยนมาใช้ Zigbee Dongle กับ Home Assistant พบว่าเสถียรขึ้นเยอะมาก อุปกรณ์แทบไม่หลุดออกจากระบบเลย แต่การติดตั้งมันเข้ากับ Synology DSM นั้นมีรายละเอียดมากกว่าอันอื่นนิดหน่อย วันนี้เราจะมาเล่าวิธีการเพื่อใครเอาไปทำกัน...
เมื่อหลายวันก่อนมีพี่ที่รู้จักกันมาถามว่า เราจะโหลด CSV ยังไงให้เร็วที่สุด เป็นคำถามที่ดูเหมือนง่ายนะ แต่พอมานั่งคิด ๆ ต่อ เห้ย มันมีอะไรสนุก ๆ ในนั้นเยอะเลยนี่หว่า วันนี้เราจะมาเล่าให้อ่านกันว่า มันมีวิธีการอย่างไรบ้าง และวิธีไหนเร็วที่สุด เหมาะกับงานแบบไหน...