Peewee模型中的getter和setter方法

时间:2016-10-17 13:00:17

标签: python peewee

我在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()

然而,为某些属性编写getter和setter感觉相当奇怪。有更多的Pythonic方式吗?例如,我是否应该使用一种方法来获取和设置指定URL的中断计数器?我应该将getter和setter函数转换为属性(尽管它们会与实际属性冲突)。欢迎反馈!

3 个答案:

答案 0 :(得分:1)

Actualy使用比例不会与您的实际属性名称冲突,因为它们可能与getter / setter函数不同。

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

假设我们有上述课程。您可以看到getter函数正在返回_value,对于那些在__init__方法中只有self.value = 5而不是self._value的人来说,这可能很奇怪。

我们接下来要说:

a = Example()

在实例化类对象之后,由于__init__value.setter正在调用self.value = 5函数,因此我们得到了:

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

正如你所看到的,你可以用这种方式使用属性并且可以使用它。

答案 1 :(得分:1)

Peewee的playhouse扩展名包括hybrid attributes,这可能正是您所需要的。它们基本上是@properties,但经过修改可以与peewee一起使用。

这是我自己的代码中的一个示例:

from peewee import *
from playhouse import hybrid    # <-- imports the hybrid extension

class User(BaseModel):
    username = CharField()
    _password = CharField()    # <-- note the underscore

    # ... other fields come here ...

    @hybrid.hybrid_property
    def password(self):
        return self._password

    @password.setter
    def set_password(self, plaintext):
        self._password = generate_password_hash(plaintext)

这旨在存储散列密码:因此,设置程序使用函数(generate_password_hash)在存储密码之前对其进行处理。

在这种情况下,您应该使用自己的函数

class SiteText(BaseModel):
    _counter = IntegerField()

    @hybrid.property
    def counter(self):
        # code to process output can come here
        return _counter

    @counter.setter
    def set_counter(self, counter):
        # code to process counter comes here
        self._counter = counter

然后,如果sSiteData对象,则可以运行s.counter = 1print s.counter等命令。数据将先使用getter和setter进行预处理,然后再另存为_counter在对象中。

最后,我建议您不要在获取器和设置器中运行save()。相反,让属性保存在对象中,然后手动运行save()将其提交到数据库。否则,您可能最终不必要地多次访问数据库,或者保存了您不想要的内容。

答案 2 :(得分:0)

由于peewee使用元类和类变量的方式,无法在__init__中定义字段,因此您必须替换名称

class SiteText(db.Model):
    url = CharField()    

    @property
    def gs_url(self):
        return self.url

    @gs_url.setter
    def gs_url(self, val):
        self.url = val