1

解决方案:错误是我的函数实际上是一个方法。

我正在尝试使用装饰器来模拟函数的变量。为什么我在下面的最后一行收到此错误?global name 'onecmd' is not defined

def static_var(varname, initial_value):
  def decorate(func):
        setattr(func, varname, initial_value)
        return func
  return decorate

@static_var("last", None)
def onecmd(self, line):
    if line == "lastcmd":
        line = onecmd.last
    else:
        onecmd.last = line
4

1 回答 1

4

您的代码似乎希望能够onecmd作为全局访问,但这是一种方法。在模块级别定义的函数确实可以通过它们的名称访问(因为它们存储为全局),但类方法仅存储在类对象中。

您需要通过定义 this 的类或通过self属性找到函数对象,然后返回类和函数:

@static_var("last", None)
def onecmd(self, line):
    onecmd = type(self).onecmd.im_func  # im_func is the wrapped function
    if line == "lastcmd":
        line = onecmd.last
    else:
        onecmd.last = line

由于您已经有一个类方法,因此最好将变量存储在中:

class Foo(object):
    last = None

    def onecmd(self, line):
        if line == "lastcmd":
            line = type(self).last
        else:
            type(onecmd).last = line

甚至将其改为类方法:

class Foo(object):
    last = None

    @classmethod
    def onecmd(cls, line):
        if line == "lastcmd":
            line = cls.last
        else:
            cls.last = line
于 2013-03-18T16:20:24.173 回答