关于python:解决装饰器和getattr

Working around decorator and getattr

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

1
2
3
4
5
6
7
8
9
10
11
12
class test:

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

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

    def method3(self, z):
        return z

我在这两种方法中都应用了装饰器,如下所示:

1
2
3
4
5
6
7
class auth:

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

但我现在明白了:

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

如果我们认为方法"method1和method2"的签名现在是"auth",那么有什么意义呢?

那么,我如何获得有或没有装饰器的参数呢?我开始读关于"检查"的文章,但是有很多关于慢的报道。


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

1
2
3
4
5
6
7
8
9
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可以被更新覆盖,例如,您定义了另一个decorator类,它也有一个member f成员。


"原始"方法存储在auth对象的f属性中。用method1.f.__code__.co_varnames代替method1.__code__.co_varnames