我在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函数转换为属性(尽管它们会与实际属性冲突)。欢迎反馈!
答案 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
然后,如果s
是SiteData
对象,则可以运行s.counter = 1
,print 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