Я пытаюсь украсить функцию, заменив ее экземпляром вызываемого класса:
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)
.
Теперь я думаю я могу ответить, почему:
Для поддержки вызовов методов функции включают метод
__get__()
для связывания методов во время доступа к атрибуту. Это означает, что все функции не являются дескрипторами данных, которые возвращают связанные или несвязанные методы в зависимости от того, вызываются ли они из объекта или класса.
Таким образом, FunctionFaker, не являясь функцией, не имеет указанного дескриптора, поэтому не искажает аргументы.
Как я могу реализовать вызываемый класс, способный заменить метод экземпляра?
MethodType
реализация__getattribute__
, что разработчики Python как-то предвидели эту потребность? Или есть другая причина? Документы по MethodType довольно скудны, есть ли какие-либо ссылки на это? 07.10.2014classobject.c
, на который я ссылался для деталей.) В Python есть несколько подобных мест; они постепенно очищаются по мере того, как разработчики PyPy и других реализаций их поднимают, но этот до сих пор не задокументирован. 07.10.2014