Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically creating @attribute.setter methods for all properties in class (Python)

I have code that someone else wrote like this:

class MyClass(object):
    def __init__(self, data):
        self.data = data

    @property
    def attribute1(self):
        return self.data.another_name1

    @property
    def attribute2(self):
        return self.data.another_name2

and I want to automatically create the corresponding property setters at run time so I don't have to modify the other person's code. The property setters should look like this:

    @attribute1.setter
    def attribue1(self, val):
        self.data.another_name1= val

    @attribute2.setter
    def attribue2(self, val):
        self.data.another_name2= val

How do I dynamically add these setter methods to the class?

like image 988
Jason Maldonis Avatar asked Mar 17 '26 03:03

Jason Maldonis


1 Answers

You can write a custom Descriptor like this:

from operator import attrgetter


class CustomProperty(object):
    def __init__(self, attr):
        self.attr = attr

    def __get__(self, ins, type):
        print 'inside __get__'
        if ins is None:
            return self
        else:
            return attrgetter(self.attr)(ins)

    def __set__(self, ins, value):
        print 'inside __set__'
        head, tail = self.attr.rsplit('.', 1)
        obj = attrgetter(head)(ins)
        setattr(obj, tail, value)


class MyClass(object):
    def __init__(self, data):
        self.data = data

    attribute1 = CustomProperty('data.another_name1')
    attribute2 = CustomProperty('data.another_name2')

Demo:

>>> class Foo():
...         pass
...
>>> bar = MyClass(Foo())
>>>
>>> bar.attribute1 = 10
inside __set__
>>> bar.attribute2 = 20
inside __set__
>>> bar.attribute1
inside __get__
10
>>> bar.attribute2
inside __get__
20
>>> bar.data.another_name1
10
>>> bar.data.another_name2
20
like image 103
Ashwini Chaudhary Avatar answered Mar 19 '26 00:03

Ashwini Chaudhary