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.