用装饰器类装饰的方法没有冻结"self"参数
我有一个用类定义的装饰器:
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的实例,结果却出现了一个错误,提示说没有传递任何参数。
1 个回答
4
我搞明白了——需要定义一个 __get__
方法,这样才能创建一个 MethodType
绑定,像这样:
def __get__(self, obj, objtype=None):
return MethodType(self, obj, objtype)
这个方法在调用对象的方法时,会创建一个 MethodType
对象,并且会冻结 self
参数。