Dynamically create class attributes Dynamically create class attributes python python

Dynamically create class attributes


You could do it without metaclasses using decorators. This way is a bit more clear IMO:

def apply_defaults(cls):    defaults = {        'default_value1':True,        'default_value2':True,        'default_value3':True,    }    for name, value in defaults.items():        setattr(cls, name, some_complex_init_function(value, ...))    return cls@apply_defaultsclass Settings(object):    pass

Prior to Python 2.6 class decorators were unavailable. So you can write:

class Settings(object):    passSettings = apply_defaults(Settings)

in older versions of python.

In the provided example apply_defaults is reusable… Well, except that the defaults are hard-coded in the decorator's body :) If you have just a single case you can even simplify your code to this:

defaults = {    'default_value1':True,    'default_value2':True,    'default_value3':True,}class Settings(object):    """Your implementation goes here as usual"""for name, value in defaults.items():    setattr(Settings, name, some_complex_init_function(value, ...))

This is possible since classes (in the sense of types) are objects themselves in Python.


I think that's case for metaclass:

class SettingsMeta(type):    def __new__(cls, name, bases, dct):        for name, value in defaults.items():            dct[name] = some_complex_init_function(value, ...)        return type.__new__(cls, name, bases, dct)class Settings(object):    __metaclass__ = SettingsMeta


When defining a class, the local namespace will be converted into the class namespace at the conclusion of the class body. As such, you can accomplish this with:

class Settings(object):    for key, val in defaults.iteritems():        locals()[key] = some_complex_init_function(val, ...)