python - 用装饰器类装饰的方法没有卡住 "self"参数

标签 python decorator

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

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 个参数。

最佳答案

弄清楚了 - 需要定义一个 __get__ 方法来创建一个 MethodType 绑定(bind),如下所示:

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

在卡住 self 参数的对象上调用方法时,它会创建一个 MethodType 对象。

关于python - 用装饰器类装饰的方法没有卡住 "self"参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5616409/

相关文章:

python - Google Wave Robot/Python 变量问题

在 Gnome Shell 中带有通知的 Python 程序不起作用

python - Django 基于类的 View - 意外的装饰器行为

css - 更改属性 jfx 装饰器

javascript - 装饰器未将渲染功能应用于 meteor + React 应用程序中的类原型(prototype)

python - 额外线程的装饰器

python - 如何根据Django中的某些字段查找重复记录

python - 向 Pandas DataFrame 添加一个新列,并使用来自单独 DataFrame 的编码数据而不使用循环?

python - 避免昂贵的 __init__ 是使用 __new__ 的好理由吗?

python - 如何将类装饰器与pickle一起使用?