__getattr__ for static/class variables in python __getattr__ for static/class variables in python python python

__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.