เมื่อเร็ว ๆ นี้ฉันเริ่มเล่นกับ Python และฉันพบสิ่งแปลก ๆ ในวิธีการปิดการทำงาน พิจารณารหัสต่อไปนี้:
adders=[0,1,2,3]
for i in [0,1,2,3]:
adders[i]=lambda a: i+a
print adders[1](3)
มันสร้างอาเรย์อย่างง่ายของฟังก์ชั่นที่รับอินพุตเดี่ยวและส่งคืนอินพุตที่เพิ่มโดยตัวเลข ฟังก์ชั่นที่มีการสร้างขึ้นในfor
วงที่การทำซ้ำโดยi
วิ่งจากไป0
3
สำหรับตัวเลขเหล่านี้แต่ละlambda
ฟังก์ชั่นจะถูกสร้างขึ้นเพื่อรวบรวมi
และเพิ่มเข้าไปในอินพุตของฟังก์ชัน บรรทัดสุดท้ายเรียกใช้lambda
ฟังก์ชันที่สองโดย3
ใช้เป็นพารามิเตอร์ 6
ที่แปลกใจของการส่งออกเป็น
4
ผมคาดว่า เหตุผลของฉันคือ: ใน Python ทุกอย่างเป็นวัตถุดังนั้นทุกตัวแปรจึงเป็นตัวชี้ที่สำคัญสำหรับมัน เมื่อสร้างlambda
ปิดสำหรับผมคาดว่ามันเก็บชี้ไปยังวัตถุจำนวนเต็มชี้ปัจจุบันโดยi
i
นั่นหมายความว่าเมื่อi
กำหนดวัตถุจำนวนเต็มใหม่มันจะไม่ส่งผลต่อการปิดที่สร้างไว้ก่อนหน้านี้ น่าเศร้าที่การตรวจสอบadders
อาร์เรย์ภายในโปรแกรมดีบั๊กเกอร์แสดงว่าทำเช่นนั้น ทุกlambda
ฟังก์ชั่นหมายถึงค่าสุดท้ายของi
, 3
ซึ่งส่งผลให้กลับมาadders[1](3)
6
ซึ่งทำให้ฉันสงสัยเกี่ยวกับสิ่งต่อไปนี้:
- สิ่งที่ปิดการจับภาพที่แน่นอน?
- เป็นวิธีที่สวยงามที่สุดในการโน้มน้าวให้
lambda
ฟังก์ชั่นในการจับมูลค่าปัจจุบันi
ในทางที่จะไม่ได้รับผลกระทบเมื่อi
เปลี่ยนค่าของมันคืออะไร?
i
ออกจากเนมสเปซได้อย่างไร
print i
จะไม่ทำงานหลังจากวง แต่ฉันทดสอบด้วยตัวเองและตอนนี้ฉันเห็นสิ่งที่คุณหมายถึง - มันใช้งานได้ ฉันไม่ทราบว่าตัวแปรวนซ้ำตามร่างกายวนในหลาม
if
, with
, try
ฯลฯ