【问题标题】:Unbound local variable problem in PythonPython中的未绑定局部变量问题
【发布时间】:2011-08-15 19:59:41
【问题描述】:

我有以下代码sn-p:

def isolation_level(level):
    def decorator(fn):
        def recur(level, *args, **kwargs):
            if connection.inside_block:
                if connection.isolation_level < level:
                    raise IsolationLevelError(connection)
                else:
                    fn(*args, **kwargs)
            else:
                connection.enter_block()
                try:
                    connection.set_isolation_level(level)
                    fn(*args, **kwargs)
                    connection.commit()
                except IsolationLevelError, e:
                    connection.rollback()
                    recur(e.level, *args, **kwargs)
                finally:
                    connection.leave_block()
        def newfn(*args, **kwargs):
            if level is None: # <<<< ERROR MESSAGE HERE, Unbound local variable `level`
                if len(args):
                    if hasattr(args[0], 'isolation_level'):
                        level = args[0].isolation_level
                elif kwargs.has_key('self'):
                    if hasattr(kwargs['self'], 'isolation_level'):
                        level = kwargs.pop('self', 1) 
            if connection.is_dirty():
                connection.commit()
            recur(level, *args, **kwargs)
        return newfn
    return decorator

它的作用真的不重要,但是我以原始形式发布它,因为我无法用更简单的东西来重现这种情况。

问题是,当我调用 isolation_level(1)(some_func)(some, args, here) 时,我在第 21 行(在清单上标记)得到 Unbound local variable 异常。我不明白为什么。我尝试重新创建不包含所有实现细节的函数和函数调用的相同结构来找出问题所在。但是我没有收到异常消息。例如以下作品:

def outer(x=None):
    def outer2(y):
        def inner(x, *args, **kwargs):
            print x
            print y
            print args
            print kwargs
        def inner2(*args, **kwargs):
            if x is None:
                print "I'm confused"
            inner(x, *args, **kwargs)
        return inner2
    return outer2

outer(1)(2)(3, z=4)

打印:

1
2
(3,)
{'z': 4}

我错过了什么??

编辑

好的,所以问题是在第一个版本中我实际上对变量执行了赋值。 Python 检测到这一点,因此假定该变量是本地变量。

【问题讨论】:

  • 错误信息可以在几行内重现,如果知道是什么原因就很容易了。见codepad.org/nI0vCx4L
  • @delnan:导致错误的最短代码是在内部函数中使用x = x :)
  • @Sven:最初是这样,但我选择让它看起来更像 OP 的代码。

标签: python function exception bug-tracking local-variables


【解决方案1】:

局部变量是在编译时确定的:变量level的赋值在该行下面几行错误发生在使该变量成为内部函数的局部变量。所以这条线

if level is None:

实际上尝试访问最内层范围内的变量level,但是这样的变量还不存在。在 Python 3.x 中,你可以通过声明来解决这个问题

nonlocal level

在内部函数的开头,如果你真的想改变外部函数的变量。否则,您可以简单地在内部函数中使用不同的变量名。

【讨论】:

  • 看,我在下面发布的清单中做了同样的事情。它不会崩溃。我不明白有什么区别。
  • @julkiewicz:不,你不会做同样的事情。在您的第二个 sn-p 中根本没有 作业。 (赋值是像a = 2 这样的行。函数内任何位置的这一行将使a 成为该函数内任何位置的局部变量。)
  • 哦,好的,所以它检测到分配。愚蠢的我。谢谢。我会接受并添加另一个编辑。谢谢。
猜你喜欢
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
  • 2010-12-01
相关资源
最近更新 更多