我正在尝试实现从数据库返回的值的缓存:
class Foo
...
def getTag(self):
value = self._Db.get(self._f[F_TAG])
setattr(self, 'tag', value)
return value
def _setTag(self, tag):
self._Db.set(self._f[F_TAG], tag)
tag = property(getTag)
...
x = Foo()
x._setTag("20")
print(x.tag)
x._setTag("40")
print(x.tag)
当我第一次处理标记属性时,它必须从数据库中获取值,并使用实例<覆盖类字段标记 以下使用的字段,但发生错误:
Traceback (most recent call last):
File "/home/altera/www/autoblog/core/dbObject.py", line 99, in <module>
print(x.tag)
File "/home/altera/www/autoblog/core/dbObject.py", line 78, in getTag
setattr(self, 'tag', value)
AttributeError: can't set attribute
答案 0 :(得分:2)
不幸的是,覆盖@property
是不可能的。这是因为@property
附加到类,而不是实例。
您可以使@property
获取者稍微复杂一点:
@property
def tag(self):
try:
return self._db_values["tag"]
except KeyError:
pass
val = self._db.get("tag")
self._db_values["tag"] = val
return val
或创建一个描述符,为您执行缓存:
Undefined = object()
class DBValue(object):
def __init__(self, column_name):
self.column_name = column_name
self.value = Undefined
def __get__(self, instance, owner):
if self.value is Undefined:
self.value = instance._db.get(self.column_name)
return self.value
class Foo(object):
tag = DBValue("tag")
答案 1 :(得分:0)
您的x.tag
是属性,没有设置器,因此当您尝试设置它时,由于显而易见的原因,您会收到错误。因此,将实际值存储在“{private}”字段中,例如x._tag
,并为其编写getter和setter。
class Foo(object):
_tag = None
@property
def tag(self):
if self._tag is None:
self._tag = self._Db.get(self._f[F_TAG])
return self._tag
@tag.setter
def tag(self, tag):
self._tag = tag
self._Db.set(self._f[F_TAG], tag)
x = Foo()
print x.tag # gets the value from the database (if necessary) or f._tag
x.tag = "bar" # sets the value in the database and caches it in f._tag