解决装饰者和getattr

时间:2017-06-12 18:55:54

标签: python python-3.x

我有解决这个问题的问题,我有以下课程:

class test:

    @auth
    def method1(self, x):
        return x

    @auth
    def method2(self, x, y):
        return x+y

    def method3(self, z):
        return z

我在两种方法中应用了装饰器,按照:

class auth:

    def __init__(self, f):
        self.f = f

    def __call__(self, *args, **kwargs):
        self.f(*args, **kwargs)

到目前为止没问题,但我需要(需要)使用以下代码:

def run():
    klass = globals()["test"]()

    method1 = getattr(klass, "method1")
    print(method1.__code__.co_varnames)
    # should print (self, x)

    method2 = getattr(klass, "method2")
    print(method2.__code__.co_varnames)
    # should print (self, x, y)

    method3 = getattr(klass, "method3")
    print(method3.__code__.co_varnames)
    # i get (self, z) < without decorator

但我现在得到了:

 AttributeError: 'auth' object has no attribute '__code__'

如果我们认为方法“method1 and method2”的签名现在是“auth”,那么有什么意义。

那么如何使用或不使用装饰器来获取参数。 我开始阅读有关“检查”的内容,但有很多关于缓慢的报道。

2 个答案:

答案 0 :(得分:1)

“原始”方法存储在f对象的auth属性中。而不是method1.__code__.co_varnames使用method1.f.__code__.co_varnames

答案 1 :(得分:1)

注释只包含一个对象,而不是它自己的对象,它是类auth的对象,而不是function。要自己访问函数,您可以编写methodN.f.__code__.co_varnames或将函数的__dict__对象的副本分配给__init__自己的auth-object。

class auth:

    def __init__(self, f):
        self.__dict__.update(f.__dict__)
        # now the initialisations
        self.f = f

    def __call__(self, *args, **kwargs):
        self.f(*args, **kwargs)

修改 您应该在更新dict后初始化members / call super,因为f可以被更新覆盖,例如。你定义了另一个装饰器类,它还有一个成员f