繁体   English   中英

在__init__中使用python @property给出属性错误

[英]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 ,但是我认为这是错误的,因为:

  1. 忽略设置器,可能会有额外的检查
  2. 如果_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM