Python - Перезаписать __getattribute__ для экземпляра? - PullRequest
3 голосов
/ 13 октября 2009

Этот мне кажется немного сложным. Некоторое время назад мне уже удалось переписать метод экземпляра что-то вроде:

def my_method(self, attr):
    pass

instancemethod = type(self.method_to_overwrite)
self.method_to_overwrite = instancemethod(my_method, self, self.__class__)

, который работал очень хорошо для меня; но теперь я пытаюсь переписать функцию экземпляра __getattribute__(), которая не работает для меня по той причине, что метод выглядит как

<type 'method-wrapper'>

Можно ли с этим что-нибудь сделать? Я не смог найти приличную документацию Python на method-wrapper.

Ответы [ 4 ]

5 голосов
/ 13 октября 2009

Вы хотите переопределить алгоритм поиска атрибута для каждого отдельного экземпляра? Не зная, почему вы пытаетесь это сделать, я рискнул бы предположить, что есть более чистый, менее замысловатый способ сделать то, что вам нужно. Если вам действительно нужно, то, как сказал Аарон, вам нужно установить на класс обработчик перенаправления __getattribute__, поскольку Python ищет специальные методы только в классе, игнорируя все, что определено в экземпляре.

Вы также должны быть особенно осторожны, чтобы не попасть в бесконечную рекурсию:

class FunkyAttributeLookup(object):
    def __getattribute__(self, key):
        try:
            # Lookup the per instance function via objects attribute lookup
            # to avoid infinite recursion.
            getter = object.__getattribute__(self, 'instance_getattribute')
            return getter(key)
        except AttributeError:
            return object.__getattribute__(self, key)

f = FunkyAttributeLookup()
f.instance_getattribute = lambda attr: attr.upper()
print(f.foo) # FOO

Кроме того, если вы переопределяете методы в своем экземпляре, вам не нужно самим создавать экземпляр объекта метода, вы можете либо использовать протокол дескриптора для функций, которые генерируют методы, либо просто указать аргумент self.

 #descriptor protocol
 self.method_to_overwrite = my_method.__get__(self, type(self))
 # or curry
 from functools import partial
 self.method_to_overwrite = partial(my_method, self)
3 голосов
/ 13 октября 2009

Есть несколько методов, которые вы не можете перезаписать, и __getattribute__() является одним из них.

1 голос
/ 13 октября 2009

Я считаю, method-wrapper - это оболочка для метода, написанного на C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...