2017-09-26 47 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!

相关问题