【问题标题】:Methods decorated with a decorator class do not have the "self" argument frozen用装饰器类装饰的方法不会冻结“self”参数
【发布时间】:2011-08-02 18:01:34
【问题描述】:

我有一个装饰器声明为一个类:

class predicated(object):
    def __init__(self, fn):
        self.fn = fn
        self.fpred = lambda *args, **kwargs: True

    def predicate(self, predicate):
        self.fpred = predicate
        return self

    def validate(self, *args, **kwargs):
        return self.fpred(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if not self.validate(*args, **kwargs):
            raise PredicateNotMatchedError("predicate was not matched")
        return self.fn(*args, **kwargs)

...当我使用它在类中包装方法时,调用该方法似乎不会将对象的实例设置为第一个参数。虽然这种行为并不完全出乎意料,但当方法成为实例方法时,我将如何让 self 被冻结?


简化示例:

class test_decorator(object):
    def __init__(self, fn):
        self.fn = fn
    def __call__(self, *args, **kwargs):
        return self.fn(*args, **kwargs)

class Foo(object):
    @test_decorator
    def some_method(self):
        print(self)

Foo().some_method()

预期的 foo 实例,却得到一个错误,指出传递了 0 个参数。

【问题讨论】:

  • +1 表示“简化示例”:)
  • 我猜是因为some_method 不再是一个函数,而是一个对象——test_decorator 类的实例——所以它不会从中创建绑定方法.我不知道如何使场景与“装饰器类”一起工作..

标签: python decorator


【解决方案1】:

想通了 - 需要定义一个 __get__ 方法才能像这样创建一个 MethodType 绑定:

def __get__(self, obj, objtype=None):
    return MethodType(self, obj, objtype)

在对冻结self 参数的对象调用方法时创建MethodType 对象。

【讨论】:

  • This 发帖谈描述符协议
猜你喜欢
  • 2020-01-11
  • 2014-01-14
  • 2019-11-16
  • 1970-01-01
  • 2013-03-10
  • 2022-08-15
  • 2019-02-03
相关资源
最近更新 更多