__getattr__ for static/class variables in python
__getattr__()
and __str__()
for an object are found on its class, so if you want to customize those things for a class, you need the class-of-a-class. A metaclass.
class FooType(type): def _foo_func(cls): return 'foo!' def _bar_func(cls): return 'bar!' def __getattr__(cls, key): if key == 'Foo': return cls._foo_func() elif key == 'Bar': return cls._bar_func() raise AttributeError(key) def __str__(cls): return 'custom str for %s' % (cls.__name__,)class MyClass: __metaclass__ = FooType# in python 3:# class MyClass(metaclass=FooType):# passprint MyClass.Fooprint MyClass.Barprint str(MyClass)
printing:
foo!bar!custom str for MyClass
And no, an object can't intercept a request for a stringifying one of its attributes. The object returned for the attribute must define its own __str__()
behavior.
(I know this is an old question, but since all the other answers use a metaclass...)
You can use the following simple classproperty
descriptor:
class classproperty(object): """ @classmethod+@property """ def __init__(self, f): self.f = classmethod(f) def __get__(self, *a): return self.f.__get__(*a)()
Use it like:
class MyClass(object): @classproperty def Foo(cls): do_something() return 1 @classproperty def Bar(cls): do_something_else() return 2
For the first, you'll need to create a metaclass, and define __getattr__()
on that.
class MyMetaclass(type): def __getattr__(self, name): return '%s result' % nameclass MyClass(object): __metaclass__ = MyMetaclassprint MyClass.Foo
For the second, no. Calling str(MyClass.Foo)
invokes MyClass.Foo.__str__()
, so you'll need to return an appropriate type for MyClass.Foo
.