2017-02-02 22 views
12

Tôi muốn viết một hàm trả về một danh sách các hàm. Là một MWe, đây là nỗ lực của tôi ở chức năng cung cấp cho ba chức năng mà thêm 0, 1, và 2 cho một số đầu vào:Làm thế nào tôi có thể trả về một hàm sử dụng giá trị của một biến?

def foo(): 
    result = [] 
    for i in range(3): 
     temp = lambda x: x + i 
     print(temp(42)) # prints 42, 43, 44 
     result.append(temp) 
    return result 

for f in foo(): 
    print(f(42)) #prints 44, 44, 44 

Trái với mong đợi của tôi, mỗi chức năng kết thúc bằng cách sử dụng giá trị cuối cùng được thực hiện bởi i. Tôi đã gặp phải hành vi tương tự khi ví dụ: một danh sách được sử dụng làm đối số cho một hàm nhưng Python thực sự sử dụng một con trỏ vào danh sách, nhưng ở đây i là một số nguyên, vì vậy tôi không hiểu những gì đang xảy ra ở đây. Tôi đang chạy Python 3.5.

Trả lời

14

đóng cửa ràng buộc cuối, có nghĩa là họ sẽ sử dụng giá trị cuối cùng của i trong phạm vi họ đã được xác định khi gọi (trong trường hợp này giá trị cuối cùng của i sẽ 2).

Các giải pháp chung cho này đang cung cấp giá trị của i như một đối số mặc định:

temp = lambda x, i=i: x + i 

Kể từ Python đánh giá đối số mặc định trong việc xây dựng một chức năng, đây là một thủ thuật giúp Python sử dụng giá trị đúng của i khi gọi được gọi, nó không tạo ra một đóng cửa và, thay vào đó, có thể nhìn i lên ở địa phương của nó.

+2

Thông tin thêm về câu trả lời này http://quickinsights.io/python/python-closures-and-late-binding/ –

+0

Cảm ơn! Chỉ cần làm cho 100% chắc chắn tôi hiểu - bởi điều này bạn có nghĩa là giá trị được sử dụng cho tất cả tôi là giá trị của i khi mã thoát khỏi phạm vi của định nghĩa hàm? – ahura

+1

Tôi thích sử dụng 'functools.partial' thay vì gán đối số mặc định, có vẻ sạch hơn. –

Các vấn đề liên quan