我在 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()
Run Code Online (Sandbox Code Playgroud)
然而,为某些属性编写 getter 和 setter 感觉相当奇怪。有没有更Pythonic的方法来做到这一点?例如,我是否应该有一个方法来获取和设置指定 URL 的中断计数器?我是否应该将 getter 和 setter 函数转换为属性(尽管它们会与实际属性发生冲突)。欢迎反馈!
Peewee 的playhouse扩展包括混合属性,这可能正是您正在寻找的。它们基本上是@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)
Run Code Online (Sandbox Code Playgroud)
这是为了存储散列密码:因此设置器使用一个函数(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
Run Code Online (Sandbox Code Playgroud)
然后,如果s是一个对象,您可以运行、等SiteData命令。数据将在保存为之前自动使用 getter 和 setter 进行预处理s.counter = 1print s.counter_counter在将数据保存到对象中
最后,我建议您不要save()在 getter 和 setter 中运行。相反,让属性保存在对象中,然后save()手动运行以将它们提交到数据库。否则,您最终可能会不必要地多次访问数据库,或者保存一些您不想要的内容。