【问题标题】:Working around decorator and getattr围绕装饰器和 getattr 工作
【发布时间】:2017-06-12 18:55:54
【问题描述】:

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

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”,这有什么意义。

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

【问题讨论】:

  • 你可以使用method1.f.__code__.co_varnames之类的东西。但总的来说,您“需要”使用的代码需要了解/与装饰器代码合作(即,它需要知道在哪里查找函数参数)。

标签: python python-3.x


【解决方案1】:

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

【讨论】:

  • 爱你兄弟!有可能知道一个方法是否有装饰器? (只是一个小问题)
  • 我不确定,但this 可能是一个开始
  • 谢谢,我可以使用 code != None 代替像链接一样的 inspect.getargspec,但无论如何,谢谢。
【解决方案2】:

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

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

【讨论】:

  • 谢谢,已经解决了,用 dict update 解决了这个问题
猜你喜欢
  • 2021-10-24
  • 1970-01-01
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
  • 2015-05-29
  • 2016-11-01
相关资源
最近更新 更多