Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write reusable @property getters/setters?

I am looking for a way to not repeat definitions for getters/setters that are structurally the same using the @property decorator. An Example:

class foo:
    def __init__(self,length):
        self.length=length
    # length
    @property
    def length(self):
        return self._length

    @length.setter
    def length(self, val):
        # do some checks here (e.g. for units, etc.) (same as in the class below)
        self._length = val


class bar:
    def __init__(self,width):
        self.width=width
    # width
    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, val):
        # do some checks here (e.g. for units, etc.)(same as in the class above)
        self._width = val

The attributes width in class bar and length in class foo have structurally the same setters so I want to define a generic setter I can apply for these attributes. However, I am not sure how to achieve the desired behaviour? Maybe with second degree decorators?

Help is greatly appreciated :)

like image 628
Tobias Triesch Avatar asked Oct 21 '25 08:10

Tobias Triesch


1 Answers

Maybe You could use python descriptor protocol to achieve what You want

class Unit(object):
    def __set_name__(self, owner, name):
        self.name = name

    def __set__(self, instance, value):
        # put validation here
        instance.__dict__[self.name] = value

    def __get__(self, instance, owner):
        if instance is None:
            # allow access to the descriptor as class attribute
            return self
        return instance.__dict__.get(self.name)


class Container:
    length = Unit()
    width = Unit()

    def __init__(self):
        self.length = 100
        self.width = 200


def main():
    t = Container()
    print(t.length)
    print(t.width)
    t.length = 3
    t.width = 15
    print(t.length)
    print(t.width)
like image 179
qwetty Avatar answered Oct 22 '25 23:10

qwetty