2017-09-26 5 views
0

Während der Behandlung der Datenbankverbindung verwendete ich das Singleton-Muster aus dem offensichtlichen Grund. Zur Vereinfachung habe ich die Klassendefinition vereinfacht, das Problem ist immer noch das gleiche.Attributfehler, Singleton-Muster mit Eigenschaftsmethode

die Klasse:

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)) 

es erzeugt folgende Fehler:

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

I die folgende Abhilfe gefunden:

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 

Die pythonic Weise Eigenschaft Methode zu verwenden, daher habe ich immer noch das Jucken, obwohl ich einen funktionierenden Code habe, kann mir jemand erklären, warum - warum ich habe so ein Fehler.

+0

Die Vertiefung. Es schmerzt. – jq170727

+0

Warum möchten Sie, dass eine Point-Klasse ein Singleton ist ?! – wim

+1

@ jq170727 Ich habe nicht auf die Einrückung geachtet, sorry, ich habe gerade den Code von meinem Editor. –

Antwort

1

Wenn self.x in Ihrer __init__ Steuerung Aufruf (über den Deskriptor) ist, bewegt sich zu den Setter für x das tut:

self._x = self._instance.x 

was wiederum ruft das Getter, die versucht zu tun:

return self._x 

vor self._x wurde festgelegt. Eine ähnliche Situation existiert für _y.

Ich habe den Eindruck, Sie wollen nicht, dass Menschen die Werte für x und y ändern, wenn das der Fall ist, machen sie read-only properties.

Als Nachtrag gibt keinen Grund, die Werte x und y in __new__, Sie in __init__ setzen sie einzustellen.

+0

Wie in meiner Frage erwähnt, ist die ursprüngliche Klasse für die Handhabung der Datenbankverbindung, daher verhindere ich mehrere Instanziierungen, und bitte ertragen Sie mit mir und stellen Sie sich x als Verbindung und y als Cursor vor. –

1

Obwohl ich bin nicht sicher, ich verstehe, warum Sie dies tun wollen würde, könnten Sie versuchen:

_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 

Ausgabe

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!

Verwandte Themen