0

In my object's init, I would like to create object properties from an iterable. For example:

class MyClass(object):
    def __init__(self, parameters):
        attributes = ['name',
                      'memory',
                      'regressors',
                      'use_const']
        for attr_name in attributes():
            try:
                attr_val = parameters[attr_name]
            except KeyError:
                raise Error("parameters must contain {}".format(attr_name))
            setattr(self, attr_name, attr_val)

This lets me get the attributes that I want. However, what I lose compared to defining

@property
def name(self):
    """str: This class' name"""
    return self._name

is that I don't get the docstrings for the properties now.

I'd like to have the docstrings for each property (for my auto-generated documentation), but I'd also like to use an iterable instead of having to define each property separately. For example, can I turn attributes into a dict with the docstring as a value, and set the attribute's docstring dynamically?

Can I have my cake and eat it too?

A.Wan
  • 1,818
  • 3
  • 21
  • 34

1 Answers1

1

You can only set property objects on the class. You can do this in a loop, but this has to be done when building the class, not instances.

Simply produce property objects:

def set_property(cls, name, attr, docstring):
    def getter(self):
        return getattr(self, attr)
    prop = property(getter, None, None, docstring)
    setattr(cls, name, prop)

for name in attributes:
    attr = '_' + name
    docstring = "str: This class' {}".format(name)
    set_property(SomeClass, name, attr, docstring)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • The difficulty with this method is I would like to perform the `set_property` loop at the class level, but at that level the class' name is not defined... Doing it outside the class definition wouldn't make it run when I do an import. I am looking into using a metaclass as described [here](http://stackoverflow.com/a/6943223/2452770) but do you have any other ideas? – A.Wan Dec 01 '15 at 22:54
  • @A.Wan: of course it runs when you import the module this is define in. The `class` statement is just code that runs at that time too. – Martijn Pieters Dec 01 '15 at 22:57