2017-06-12 29 views
0

我有问题,解决这个问题,我有下面的类:工作和getattr的

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和method2”的签名现在是“auth”,那么有意义。

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

+0

你可以使用像'method1.f .__ code __。co_varnames'这样的东西。但是通常你需要使用的代码需要知道/与装饰器代码协作(即它需要知道在哪里寻找函数参数)。 – BrenBarn

回答

1

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

+0

爱你兄弟!有可能知道一个方法是否有装饰器? (只是一个小问题) – Jonny

+0

我不确定,但[this](https://stackoverflow.com/questions/19314405/how-to-detect-is-decorator-has-been-applied-to-method-或功能)可能在某处开始 –

+0

谢谢,我可以使用__code__!=无,而是像链接inspect.getargspec,但无论如何感谢的人。 – Jonny

1

注解只包含一个对象,不是对象itsself,它是auth类的一个对象,而不是function。要自己访问该功能,可以编写methodN.f.__code__.co_varnames或将该函数的__dict__对象的副本分配给自己的验证对象。

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) 

编辑: 你应该初始化成员/调用super更新字典之后,因为f可以通过更新,如被覆盖。你定义了另一个装饰者类,它也有一个成员f

+0

谢谢,它已解决,并与字典更新很好的解决方法 – Jonny