Gần đây tôi bắt đầu chơi xung quanh với Python và tôi đã bắt gặp một thứ gì đó đặc biệt trong cách đóng cửa hoạt động. Hãy xem xét các mã sau đây:
adders=[0,1,2,3]
for i in [0,1,2,3]:
adders[i]=lambda a: i+a
print adders[1](3)
Nó xây dựng một mảng đơn giản các hàm lấy một đầu vào và trả về đầu vào đó được thêm bởi một số. Các hàm được xây dựng theo forvòng lặp trong đó trình vòng lặp ichạy từ 0đến 3. Đối với mỗi số này, một lambdahàm được tạo để bắt ivà thêm nó vào đầu vào của hàm. Dòng cuối cùng gọi lambdahàm thứ hai với 3tham số. Tôi ngạc nhiên đầu ra là 6.
Tôi mong đợi a 4. Lý do của tôi là: trong Python mọi thứ đều là một đối tượng và do đó, mỗi biến là một con trỏ cần thiết cho nó. Khi tạo các bao lambdađóng cho i, tôi dự kiến nó sẽ lưu một con trỏ tới đối tượng số nguyên hiện được trỏ tới i. Điều đó có nghĩa là khi iđược gán một đối tượng số nguyên mới, nó sẽ không ảnh hưởng đến các bao đóng được tạo trước đó. Đáng buồn thay, kiểm tra addersmảng trong trình gỡ lỗi cho thấy rằng nó làm. Tất cả các lambdahàm đề cập đến giá trị cuối cùng của i, 3kết quả là adders[1](3)trả về 6.
Điều này làm tôi tự hỏi về những điều sau đây:
- Những gì đóng cửa chụp chính xác?
- Cách thanh lịch nhất để thuyết phục các
lambdachức năng để nắm bắt giá trị hiện tại củaitại theo cách sẽ không bị ảnh hưởng khiithay đổi giá trị của nó là gì?
iđể rời khỏi không gian tên?
print isẽ không hoạt động sau vòng lặp. Nhưng tôi đã thử nó cho chính mình và bây giờ tôi thấy ý của bạn - nó hoạt động. Tôi không có ý tưởng rằng các biến vòng lặp kéo dài sau thân vòng lặp trong python.
if, with, try, vv