在类方法中使用装饰器并填充变量

时间:2018-02-28 16:21:18

标签: python python-3.x

我正在写一些代码,我有一个字典,其中键是任何字符串,值是一个函数。然后我循环遍历字典中的每个键并调用函数,如下所示:

class SomeClass:

    dictionary = {}

    # Not sure how to use this decorator function
    def decorator(key):
        def wrapper(funct):
            self.dictionary[key] = funct
            return funct
        return wrapper


    @decorator("some_val1")
    def function_1(self):
       ...

    @decorator("some_val2")
    def function_2(self):
       ...

    @decorator("some_val3")
    def function_3(self):
       ...

    def execute_all_functions(self):
        for key, _ in self.dictionary.items():
            self.dictionary[key]()


if __name__ == "__main__":
    sclass = SomeClass()
    sclass.execute_all_functions()

所以这应该填充dictionary

{
   "some_val1": function_1(),
   "some_val2": function_2(),
   "some_val3": function_3()
}

我收到此错误

self.dictionary[key] = funct
NameError: name 'self' is not defined

我怎么能做到这一点。帮助赞赏。

2 个答案:

答案 0 :(得分:0)

wraps可能有用。在下面这个简单的例子中,如果没有from functools import wraps class SomeClass: var = 1 @wraps def decorator(self, fn): return fn @decorator def return_value(self): print(self.var) return self.var if __name__ == "__main__": sclass = SomeClass() sclass.return_value() ,装饰器将无法正常运行。

{{1}}

答案 1 :(得分:0)

我认为不可能。

首先你应该阅读:https://docs.python.org/3.3/howto/descriptor.html,以了解功能与方法的区别。

在您的代码中,密钥等于方法的self

def decorator(key):
    def wrapper(funct):
        self.dictionary[key] = funct
        return funct
    return wrapper

如果您想使用课程的属性,请引用cls。正确的代码可能是:

@classmethod
def decorator(cls, key):
    def wrapper(funct):
        self.dictionary[key] = funct
        return funct
    return wrapper

因此,如果您想要更新类属性,则必须提供cls引用。我尝试过以下代码,将decorator_maker作为一种类方法。

class SomeClass:

    dictionary = {}

    @classmethod
    def decorator_maker(cls, key):
        print(cls, key)
        def decorator(funct):
            cls.dictionary[key] = funct
            return funct
        return decorator

    @decorator_maker("some_val1")
    def function_1(self):
       ...

    @decorator_maker("some_val2")
    def function_2(self):
       ...

    @decorator_maker("some_val3")
    def function_3(self):
       ...

    def execute_all_functions(self):
        for key, _ in self.dictionary.items():
            self.dictionary[key]()

你会收到类似TypeError: 'classmethod' object is not callable的错误。与此问题相同:'classmethod' object is not callable。 AKA,你无法调用类方法,直到定义了类。

所以你可能想让装饰者在课外。但出于同样的原因,在课堂方法之前,您无法获得cls的引用。 method也是类的属性,您无法在定义另一个属性时动态更改属性。见Python class method run when another method is invoked

如果将dictionary移到课堂外,会更容易。