งงกับ closure ของ Python
วันนี้นั่งหา bug มานาน สุดท้ายก็เจอ แต่ไม่ใช่ bug แต่เป็นความเข้าใจผิดนิดหน่อย ต่อไปนี้เป็น code Python ที่เขียนขึ้นมาทดสอบไอเดีย
code นี้จะ print ออกมา 4 บรรทัด ถ้าคิดว่าได้แบบนี้
1a 1b 2a 2b
ยินดีด้วย คุณเข้าใจผิดเหมือนผม คงเป็นเพราะ background จากภาษาอื่นทำให้คิดแบบนั้น จริงๆมันได้
2b 2b 2b 2b
ทำไม? เพราะ lambda ถูกนิยามใน environment ของ funcList และ x, y ใน lambda จะ bind กับ ตัวแปร x,y ไม่ใช่ bind กับค่าใน x, y ณ ตอนที่ lambda ถูกนิยาม ตอนรันจึงได้ x, y เป็นค่าสุดท้ายหลังจาก for loop รันเสร็จ ซึ่งก็คือ 2, b
ถ้าอยากให้ x, y bind กับค่าของ x, y ณ ตอนนั้น ก็ต้องสร้าง environment ใหม่ที่ x, y ไม่เปลี่ยนแปลง แล้วไป bind กับ x, y ใน environment ใหม่นั่น แบบนี้
ตัวอย่างที่ 2 นี้ ตรง
lambda: x+y
อยู่ใน environment ของ ffPlus ซึ่งไม่มีการเปลี่ยนค่าของ x, y เลย ถ้าใช้ funcList2 ใน main อันเดิมจะได้
1a 1b 2a 2b
ข้อมูล