Attrs: Create attributes with properties dynamically

Created on 20 Feb 2017  路  6Comments  路  Source: python-attrs/attrs

Suppose I have a dict which items should be the attributes of a automatically created class:

>>> import attr
>>> attributes = dict(a = attr.ib(default=1),  b = attr.ib(default=2))
>>> My = attr.make_class('My', attributes)
>>> my = My()
>>> my
My(a=1, b=2)

Now I want to convert the attributes into properties automatically in order to check if the setting value is positive:

>>> my.a = -1
ValueError: Use only positiv values!

BTW: I dont want to use the underscore representation:

>>> my
My(_a=1, _b=2)

What technique can I use?

  • In order to use porperties I have to accept the underscore notation which I don't like to explain to my customers

  • The validator and converter function are only applied at the instantiation

  • I can't use descriptors because I suppose attrs is using them

Most helpful comment

Doesn't @Tinche 's solution mean that when I create a My object, then I would write My(_a = 1) instead of My(a = 1)?

All 6 comments

attrs doesn鈥檛 use descriptors at this point. It just collects the attributes from the class body and writes a __init__ according to them. We鈥檒l even go on and delete the Attribute instances from the class body by December this year.

Thanks for the infos.

Currently I would like to write something like

>>> import attr
>>> My = attr.make_class('My', dict( a = attr.ib(pget=getter_func, pset=setter_func) ))
>>> My(3)
My(a=3)

Where setter_func just checks if self._a > 0.

Do you think this would be possible? Or does it breaks some other features?

IMO, it'd add complexity to attr.ib() for a use case only useful for make_class. Just rewrite your class:

@attr.s
class My:
    _a = attr.ib()

    @property
    def a(self):
        return self._a

    @a.setter
    def a(self, value):
        self._a = value

make_class is more for quick'n'dirty class definitions.

Yeah I鈥檓 with Tin on this, sorry.

It could be useful when you use attrs.asdict() as a step in serialization of an attr.s() and would like the property to be included in the dict.

Doesn't @Tinche 's solution mean that when I create a My object, then I would write My(_a = 1) instead of My(a = 1)?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Bananaman picture Bananaman  路  7Comments

gabbard picture gabbard  路  6Comments

indigoviolet picture indigoviolet  路  8Comments

Tinche picture Tinche  路  15Comments

RonnyPfannschmidt picture RonnyPfannschmidt  路  7Comments