Loops không giới thiệu phạm vi trong Python, vì vậy tất cả ba chức năng gần trên cùng một biến i
, và sẽ đề cập đến giá trị cuối cùng của mình sau khi kết thúc vòng lặp, mà là 2.
Có vẻ như tất cả mọi người gần tôi nói chuyện với những người sử dụng bao đóng trong Python đã bị cắn bởi điều này. Hệ quả là hàm bên ngoài có thể thay đổi i
nhưng hàm bên trong không thể (vì điều đó sẽ làm cho i
một địa phương thay vì đóng cửa dựa trên các quy tắc cú pháp của Python).
Có hai cách để giải quyết này:
# avoid closures and use default args which copy on function definition
for i in xrange(3):
def func(x, i=i):
return x*i
flist.append(func)
# or introduce an extra scope to close the value you want to keep around:
for i in xrange(3):
def makefunc(i):
def func(x):
return x*i
return func
flist.append(makefunc(i))
# the second can be simplified to use a single makefunc():
def makefunc(i):
def func(x):
return x*i
return func
for i in xrange(3):
flist.append(makefunc(i))
# if your inner function is simple enough, lambda works as well for either option:
for i in xrange(3):
flist.append(lambda x, i=i: x*i)
def makefunc(i):
return lambda x: x*i
for i in xrange(3):
flist.append(makefunc(i))
Nguồn
2012-07-10 07:33:45
thể trùng lặp của [đóng cửa từ vựng bằng Python] (http://stackoverflow.com/questions/233673/lexical-closures-in-python) – BrenBarn