Search code examples
pythonpeewee

Getter and setter methods in a Peewee model


I have the following simple model in Peewee:

class SiteText(BaseModel):
    url = TextField()
    text = TextField()
    my_counter = IntegerField()

    def get_text_by_url(url):
        d = [s.text for s in SiteText.select(SiteText.url == url)]
        d = d[0] if len(d) > 0 else None
        return d

    def save_text(updates):
        # updates is a dict containing, url, text, my_counter
        SiteText.upsert(**updates)

    def get_outage_counter(url):
        c = [c.my_counter for c in SiteText.select(SiteText.url == url)]
        c = c[0] if len(c) > 0 else None
        return c

    def set_outage_counter(url, counter):
        c = SiteText.get(SiteText.url == url)
        c.counter = counter
        c.save()

However, it feels rather strange writing getters and setters for some of the attributes. Is there a more Pythonic way of doing this? Should I, for example, have a single method for getting and setting the outage counter for a specified URL? Should I convert the getter and setter functions to properties (though then they would clash with the actual attributes). Feedback welcome!


Solution

  • Actually using properties wouldn't clash with your attribute name, because they can be different than the getter/setter function.

    class Example:
        def __init__(self):
           self.value = 5
    
        @property
        def value(self):
            print('Entering value getter')
            return self._value
    
        @value.setter
        def value(self, val):
            print('Entering value setter')
            self._value = val
    

    Lets say we have the class as above. You can see that the getter function is returning _value which might be strange for someone who would see that in the __init__ method there is only self.value = 5 but not self._value.

    Lets say that we do this next:

    a = Example()
    

    Just after instantiating the class object, __init__ is calling the value.setter function due to self.value = 5, and because of that, we got:

    a = Example()
    Entering value setter
    print(a.value)
    Entering value getter
    5
    print(a.__dict__)
    {'_value': 5} # _value was created in setter function
    

    So as you can see, you can use properties this way and be fine with it.