【发布时间】:2014-12-01 07:48:08
【问题描述】:
我正在尝试通过将函数替换为可调用类的实例来装饰函数:
class FunctionFaker( object ):
def __init__( self, f ):
self.f= f
def empty_function( self ):
pass
def __call__( self, *args, **kwargs ):
self.f( *args, **kwargs)
def fakefunction( f ):
'''a decorator that transforms a function into a FunctionFaker'''
return FunctionFaker(f)
@fakefunction
def dosomething():
pass
dosomething.empty_function()
dosomething()
这按预期工作。
但是,一旦我尝试装饰类方法:
class Test( object ):
@fakefunction
def dosomething(self):
pass
t=Test()
t.dosomething.empty_function()
t.dosomething()
我收到了TypeError: dosomething() takes exactly 1 argument (0 given)。
现在,我想I can answer the why:
为了支持方法调用,函数包括
__get__()方法,用于在属性访问期间绑定方法。这意味着所有函数都是非数据描述符,它们返回绑定或未绑定的方法,具体取决于它们是从对象调用还是从类调用。
所以,FunctionFaker,不是一个函数,没有上述描述符,因此不会破坏参数。
如何实现一个能够替换实例方法的可调用类?
【问题讨论】:
-
我刚刚意识到我可以简单地实现
__get__并返回types.MethodType,但我真的不明白这样做仍然可以让您调用empty_function。它只是成为MethodType实例的一个属性吗?这是明智的做法吗? -
签名是
types.MethodType(callable, instance, class),您可以传递任何类型的可调用对象,包括具有__call__函数的类的实例。