Как я переопределяю __ getattr __ в Python, не повреждая поведение по умолчанию?

Я хочу переопределить __getattr__ метод на классе, чтобы сделать что-то полагает, но я не хочу повреждать поведение по умолчанию.

Что корректный путь состоит в том, чтобы сделать это?

177
задан dreftymac 25 October 2017 в 18:42
поделиться

2 ответа

Переопределение __getattr__ должно быть в порядке -- __getattr__ вызывается только в крайнем случае, т.е. если в экземпляре нет атрибутов, соответствующих имени. Например, если вы обращаетесь к foo.bar, то __getattr__ будет вызван только в том случае, если foo не имеет атрибута под названием bar. Если атрибут такой, который вы не хотите обрабатывать, поднимите AttributeError:

class Foo(object):
    def __getattr__(self, name):
        if some_predicate(name):
            # ...
        else:
            # Default behaviour
            raise AttributeError

Однако, в отличие от __getattr__, __getattribute__ будет вызван первым (работает только для новых классов стилей, т.е. тех, которые наследуются от object). В этом случае вы можете сохранить поведение по умолчанию следующим образом:

class Foo(object):
    def __getattribute__(self, name):
        if some_predicate(name):
            # ...
        else:
            # Default behaviour
            return object.__getattribute__(self, name)

См. подробнее в документации Python.

257
ответ дан 23 November 2019 в 20:19
поделиться
class A(object):
    def __init__(self):
        self.a = 42

    def __getattr__(self, attr):
        if attr in ["b", "c"]:
            return 42
        raise AttributeError("%r object has no attribute %r" %
                             (self.__class__.__name__, attr))

>>> a = A()
>>> a.a
42
>>> a.b
42
>>> a.missing
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in __getattr__
AttributeError: 'A' object has no attribute 'missing'
>>> hasattr(a, "b")
True
>>> hasattr(a, "missing")
False
32
ответ дан 23 November 2019 в 20:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: