Python Meta-programming Gotcha With __getattr__
Recently I’ve been working with Python at work. I’ve had to create a very lightweight ORM and each model class derived from the base model class. However, to access the fields in an instance of a model class required some meta-programming. This was pretty straight forward since Python provides the
__getattr__ that gets executed when a field is not found. But I did run into one gotcha!
__getattr__ method, I was determining the value of the property that was being accessed from an internal dictionary that stored the values of the model fields. However, something really strange was happening. The
__getattr__ method was being called for properties that were defined directly on the class. An example of this can be seen here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
It turns out that what was happening was that I was trying to access the
boom property from the
Example class and it was trying to be retrieved from the
__getattr__ method implementation. This threw me for a loop because I am still fairly new to Python.
From the example above you can see that the
foo property works correctly, but the
boom property runs the
__getattr__ method when accessed. If an exception is thrown in the
@property method, the Python class will revert to using the
__getattr__ method. Once I addressed the underlying exception everything worked properly.