奇怪的Python函数作用域行为

奇怪的Python函数作用域行为,python,Python,我对这个范围行为感到困惑: class Bar: def __init__(self): for fn in ["open","openW","remove","mkdir","exists","isdir","listdir"]: print "register", fn def func_wrapper(filename): print "called func wrapper", fn,

我对这个范围行为感到困惑:

class Bar:
    def __init__(self):
        for fn in ["open","openW","remove","mkdir","exists","isdir","listdir"]:
            print "register", fn
            def func_wrapper(filename):
                print "called func wrapper", fn, filename
            setattr(self, fn, func_wrapper)

bar = Bar()
bar.open("a")
bar.remove("b")
bar.listdir("c")
这将提供以下输出:

register open
register openW
register remove
register mkdir
register exists
register isdir
register listdir
called func wrapper listdir a
called func wrapper listdir b
called func wrapper listdir c
但我本以为
func_wrapper
始终是正确的函数。我知道
func_wrapper
的作用域是整个函数,但我在每次循环迭代中都重新定义了它,最后一个实例保存在attrib中。我还尝试在
setattr
下添加
func\u wrapper=None
,但这没有帮助(我也会感到奇怪……)

我瞎了吗?我甚至不知道如何解决/修复这个问题。

class Bar:
    def __init__(self):
        for fn in ["open","openW","remove","mkdir","exists","isdir","listdir"]:
            print "register", fn
            def func_wrapper(filename, fn=fn):
                print "called func wrapper", fn, filename
            setattr(self, fn, func_wrapper)
或者,更有力地说,与

def mkwrapper(fn):
    def func_wrapper(filename):
        print "called func wrapper", fn, filename
    func_wrapper.__name__ = fn
    return func_wrapper

class Bar:
    def __init__(self):
        for fn in ["open","openW","remove","mkdir","exists","isdir","listdir"]:
            print "register", fn
            func_wrapper = mkwrapper(fn)
            setattr(self, fn, func_wrapper)

在原始示例中,所有生成的函数都访问相同的外部变量
fn
,该变量在每次循环运行中都会发生变化。在更正的示例中,这是被阻止的。

啊,是的,我认为是这样的……)我一直认为在后期绑定方面,
lambda
有一些特殊之处,但现在我了解到常规函数确实存在同样的问题,只是它们不像lambda函数那样经常使用+我真的希望人们不要再推荐那个默认参数黑客了。@heltonbiker:你能详细说明一下吗?在这里我应该如何使用dict?为什么?我读得更透彻了,删除了之前的评论。