You almost had it - just define it the getter as a class method (also you had a small syntax error, attr is a string here):
class Headings:
standard_heading = {
'height': 3.72,
'width': 25.68,
'left': 1.65,
'top': 0.28
}
@classmethod
def __getattribute__(cls,attr):
return {k:v*10 for k,v in cls.__dict__[attr].items()}
print(Headings().standard_heading)
Note you do need an actual instance for this to work, but that's what you use in your example. This will also ruin get attribute for object specific fields defined within any method of the object (such as __init__), so careful with this. An easy fix is to override also:
@classmethod
def __getattribute__(cls,attr):
try:
return {k:v*10 for k,v in cls.__dict__[attr].items()}
except: raise AttributeError(attr)
def __getattr__(self,attr):
return object.__getattribute__(self,attr)
So now if you have:
def __init__(self): self.a = 'abc'
then
print(Headings().a)
will also work. Explanation:
- First
__getattribute__ is called as a class method.
- If no class variable exists, then
__getattr__ is invoked, now as a regular method, so with the actual object (and object members).
- Call the
object __getattribute__ to fall back to normal behavior.
Last note - other than your specific question, if you just want to define a special getter for one class member, a safer way that will only affect said member is using @property and @getter -as explained for example in How does the @property decorator work?. Thanks Adonis for pointing that out.