Search code examples
pythonattributesoperator-overloadinggetattrgetattribute

Does__getattr__ allow modifying passed value?


This is my code:

class myclass:
    def __init__(self):
        self.value = 5

    def __getattr__(self, attrname):
        if attrname == 'value':
            return 10

X = myclass()
print X.value

I suppose the output value should be 10 (__getattr__ modifies returned value). However output is 5.

If I remove initialization of value:

class myclass:

    def __getattr__(self, attrname):
        if attrname == 'value':
            return 10

X = myclass()
print X.value

It works as expected (returns 10). Why?


Solution

  • __getattr__ is only used for missing attributes. See the documentation:

    Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self).

    In your first example, 'value' is not a missing attribute; it was set in __init__. Note that it doesn't matter where it was set, only that it exists.

    If you must intercept all attribute access, you need to implement the __getattribute__ hook instead.