derricw
derricw

Reputation: 7036

Changing __getattr__ during instantiation

I am wanting to change __getattr__ during instantiation of the class. For example:

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

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

I would have expected this to behave like:

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

But it does not.

For example, when I run:

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

I would expect both classes to print Getting test, but the top class throws an AttributeError.

Can __getattr__ not be changed in this way?

Upvotes: 5

Views: 95

Answers (1)

wim
wim

Reputation: 362707

For special methods like __getattr__, Python searches in the base(s) __dict__, not in the instance __dict__.

You can read more details about this in the special lookup section of the data model documentation.

I have two implementations of __getattr__ that each use a different type of serialization (json, pickle), and I wanted my class to be able to select one based on a kwarg.

This is not a good use-case for overriding __getattr__. Abandon this idea, and instead consider to use @property or descriptors to handle your serialisation dynamically.

Upvotes: 2

Related Questions