程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

奇怪的Python函数作用域行为

发布于2019-10-14 21:16     阅读(381)     评论(0)     点赞(6)     收藏(3)


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

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是整个函数,但是我在每次循环迭代中都重新定义了它,最后一个实例保存在属性中。我还尝试在的func_wrapper = None下面添加内容setattr但这无济于事(也想知道我...)。

我是盲人吗?我什至没有真正看到如何解决/解决此问题。


解决方案


要么与

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,该变量在每次循环运行中都会更改。在更正的示例中,这是可以避免的。



所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:https://www.pythonheidong.com/blog/article/136844/831016e0a920d5247dcd/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

6 0
收藏该文
已收藏

评论内容:(最多支持255个字符)