我有一个Text()类,它会缓存它的表面以进行渲染,除非字体/大小发生变化。 (我从代码段中删除了字体属性)
self.size
中使用__init__
,则会失败:Traceback (most recent call last):
File "temp.py", line 21, in <module>
t = Text("arial", 6)
File "temp.py", line 3, in __init__
self.size = size
File "temp.py", line 16, in size
if self._size != px:
AttributeError: 'Text' object has no attribute '_size'
我能够在self._text
分配__init__
,但我认为这是错误的,因为:
_text
发生变化,class Text(object):
def __init__(self, font, size=12):
self.size = size
self.font = font
self.dirty = False
def draw(self):
print "Draw: ", self.size, self.font, self.dirty
@property
def size(self):
return self._size
@size.setter
def size(self, px):
if self._size != px:
self._size = px
self.dirty=True
if __name__ == "__main__":
t = Text("arial", 6)
t.draw()
t.size = 8
t.draw()
class Text(object):
def __init__(self, font, size=12):
self.size = size
self.font = font
self.dirty = False
def draw(self):
print "Draw: ", self.size, self.font, self.dirty
@property
def size(self):
return self._size
@size.setter
def size(self, px):
try:
if self._size != px:
self._size = px
self.dirty=True
except:
self._size = 14
self.dirty = True
if __name__ == "__main__":
t = Text("arial", 6)
t.draw()
t.size = 8
t.draw()
答案 0 :(得分:3)
try:
if self._size != px:
self._size = px
self.dirty=True
except:
self._size = 14
self.dirty = True
除了一个坏主意,因为你捕获所有异常。您可能会意外地捕获其他异常并忽略它。那将是个坏主意。 Python出于各种原因抛出异常,你最终会掩盖一个bug。出于同样的原因,您应该尽可能少地在try块中添加代码。
一种方法是:
try:
size_changed = self._size != size
except AttributeError:
size_changed = True
if size_changed:
self._size = size
self.dirty = True
但是解决这个问题的方法更简洁:
def __init__(self, font, size=12):
# store something in the hidden attribute
# so it will work as expected
self._size = None
self.size = size
self.font = font
self.dirty = False
答案 1 :(得分:2)
我使用的模式是:
class Text(object):
def __init__(self, font, size=12):
self.font = font
self._size = size
self.dirty = False
@property
def size(self):
return self._size
@size.setter
def size(self, px):
if self._size != px:
self._size = px
self.dirty = True
您遇到的问题是您的setter指的是在调用setter之前您未创建的属性 - self._size
在您为其分配内容之前不存在。通常,我使用具有良好名称的属性(如size
)并将数据存储在隐藏属性中(例如,_size
)。在初始化程序中,我只是直接操作属性而不依赖于属性。
在您的情况下,设置属性会产生副作用,因此您可能会出现错误。请考虑如果将self.dirty = False
作为初始化程序中的第一行,会发生什么。