![](/img/trans.png)
[英]Python class Attribute Error even though attribute is in __init__
[英]using python @property in __init__ , gives attribute error
我有一个Text()类,它缓存要渲染的表面,除非字体/大小改变。 (我从代码段中删除了font属性)
__init__
使用self.size
,它将失败: 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'
我可以在__init__
分配self._text
,但是我认为这是错误的,因为:
_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()
try:
if self._size != px:
self._size = px
self.dirty=True
except:
self._size = 14
self.dirty = True
例外是一个坏主意,因为您会捕获所有异常。 您可能不小心捕获了其他一些异常而忽略了它。 那将是一个坏主意。 Python出于各种原因引发异常,您最终将掩盖错误。 出于同样的原因,您应该在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
我使用的模式是:
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
您遇到的问题是,设置器引用的是直到调用该设置器后才创建的属性self._size
在您为其分配了某些内容之前不存在。 通常,我使用名称很好的属性(例如size
)并将数据存储在隐藏的属性(例如_size
)中。 在初始化程序中,我仅直接操作属性,而不依赖属性。
在您的情况下,设置该属性会有副作用,因此您有可能会爬入错误。请考虑一下,如果将self.dirty = False
为初始化的第一行会发生什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.