2016-09-07 2 views
4

Я хочу изменить __getattr__ во время создания класса. Например:Изменение __getattr__ во время создания

class AttrTest(object): 
    def __init__(self): 
     self.__getattr__ = self._getattr 

    def _getattr(self, attr): 
     print("Getting {}".format(attr)) 

Я бы ожидал вести себя, как:

class AttrTest(object): 
    def __getattr__(self, attr): 
     print("Getting {}".format(attr)) 

Но это не так.

Например, когда я бегу:

>>> at = AttrTest() 
>>> at.test 

я ожидал бы оба класса для печати Getting test, но верхний класс бросает AttributeError.

Can __getattr__ Не может быть изменено таким образом?

+0

Ответный вопрос, который у меня есть, естественно, «почему?» –

+0

@WayneWerner хорошо, у меня есть две реализации '__getattr__', каждая из которых использует различный тип сериализации (json, pickle), и я хотел, чтобы мой класс мог выбрать его при создании экземпляра на основе kwarg. – ballsatballsdotballs

+0

Почему не подклассы? Предположительно, вызывающий абонент знает, что есть, поскольку они устанавливают kwarg –

ответ

3

Для специальных методов, таких как __getattr__, Python ищет в базе (ах) __dict__, а не в случае __dict__.

Более подробную информацию об этом можно найти в разделе документации модели данных special lookup.

У меня есть две реализации __getattr__, что каждый использовать другой тип сериализации (JSON, рассол), и я хотел, чтобы мой класс, чтобы быть в состоянии выбрать один на основе kwarg.

Это нехороший прецедент для переопределения __getattr__. Отбросьте эту идею и вместо этого подумайте о том, чтобы использовать @property или descriptors для динамической обработки сериализации.

+1

TIL ... это! :) –

+0

@ballsatballsdotballs - у вас есть '__getattr__' call' _getattr', который установлен на '_getattrjson' или' _getattrpickle' на основе аргументов инициализации? – mgilson

+0

@mgilson Это сработает, да. – ballsatballsdotballs

Смежные вопросы