2017-09-26 46 views
0

在處理數據庫連接時,出於明顯的原因,我使用了單例模式。爲了簡化目的,我簡化了類的定義,問題仍然是一樣的。屬性錯誤,具有屬性方法的單身模式

類:

class Point(object): 
    _instance = None 

    def __new__(cls, x, y): 
     if Point._instance is None: 
      Point._instance = object.__new__(cls) 
      Point._instance.x = x 
      Point._instance.y = y 
     return Point._instance 

    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

    @property 
    def x(self): 
     return self._x 

    @x.setter 
    def x(self, x): 
     self._x = self._instance.x 

    @property 
    def y(self): 
     return self._y 

    @y.setter 
    def y(self, y): 
     self._y = self._instance.y 

    def __str__(self): 
     return 'x: {}, y: {} id.x: {}'.format(self.x, self.y, id(self.x)) 

它生成以下錯誤:

AttributeError: 'Point' object has no attribute '_x' 

我已經發現了以下解決方法:

class Point(object): 
    _instance = None 

    def __new__(cls, x, y): 
     if Point._instance is None: 
      Point._instance = object.__new__(cls) 
      Point._instance.x = x 
      Point._instance.y = y 
     return Point._instance 

    def __init__(self, x, y): 
     self.x = self._instance.x 
     self.y = self._instance.y 

的Python的方式是使用屬性的方法,因此即使我有一個工作代碼,我仍然有這種癢,有人可以向我解釋爲什麼 - 我爲什麼這樣的錯誤。

+0

縮進。好痛。 – jq170727

+0

爲什麼你想要一個Point類是單身人士? – wim

+1

@ jq170727我沒有注意到縮進對不起,我只是從我的編輯過去的代碼。 –

回答

1

當你__init__,控制調用self.x(通過描述符)是移動到制定者x其作用:

self._x = self._instance.x 

,反過來,調用它試圖做的getter:

return self._x 

之前self._x已設置。 _y存在類似的情況。

我的印象是,你不想讓人們改變xy的值,如果是這樣的話,就讓他們read-only properties

作爲附錄,沒有理由將xy的值設置爲__new__,您將它們設置爲__init__

+0

正如我的問題所提到的,原來的類是用於處理數據庫連接的,因此我阻止了多個實例化,請耐心等待,並將x想象爲連接,將y想象爲光標。 –

1

雖然我不知道我理解你爲什麼會想這樣做,你可以嘗試:

_instance = None 

def Point(x,y): 
    class _Point(object): 
     def __init__(self, x, y): 
      self.x = x 
      self.y = y 
     def __str__(self): 
      return 'x: {}, y: {} id.x: {}'.format(self.x, self.y, id(self.x)) 
    global _instance 
    if _instance is None: 
     _instance = _Point(x,y) 
    return _instance  

p1 = Point(1,2) 
print "p1", p1 

p2 = Point(3,4) 
p2.x = 10 
print "p2", p2 

print "p1", p1 

輸出

p1 x: 1, y: 2 id.x: 94912852734312 
p2 x: 10, y: 2 id.x: 94912852734096 
p1 x: 10, y: 2 id.x: 94912852734096 

Try it online!

相關問題