Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically create class attributes

Tags:

I need to dynamically create class attributes from a DEFAULTS dictionary.

defaults = {
    'default_value1':True,
    'default_value2':True,
    'default_value3':True,
}

class Settings(object):
    default_value1 = some_complex_init_function(defaults[default_value1], ...)
    default_value2 = some_complex_init_function(defaults[default_value2], ...)
    default_value3 = some_complex_init_function(defaults[default_value3], ...)

I could also achive this by having sth. like __init__ for class creation, in order to dynamically create these attributes from dictionary and save a lot of code and stupid work.

How would you do this?

Thank you very much in advance!

like image 555
xyz-123 Avatar asked Apr 06 '10 08:04

xyz-123


People also ask

What are dynamic attributes in Python?

Dynamic attributes in Python are terminologies for attributes that are defined at runtime, after creating the objects or instances. In Python we call all functions, methods also as an object. So you can define a dynamic instance attribute for nearly anything in Python.

How do you create a class object dynamically in Python?

Python Code can be dynamically imported and classes can be dynamically created at run-time. Classes can be dynamically created using the type() function in Python. The type() function is used to return the type of the object. The above syntax returns the type of object.

How do I add an attribute to a class in Python?

Adding attributes to a Python class is very straight forward, you just use the '. ' operator after an instance of the class with whatever arbitrary name you want the attribute to be called, followed by its value.


1 Answers

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_defaults
class Settings(object):
    pass

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

class Settings(object):
    pass
Settings = 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.

like image 66
nkrkv Avatar answered Oct 30 '22 10:10

nkrkv