Pyro: Methode von RemoteObjekt nur einmal aufrufbar

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Hallo,
versuche gerade eine RemoteDB Schnittstelle mit Pyro zu entwickeln.
Hier Ausschnitte vom Quelltext.
Remote Klasse:

Code: Alles auswählen

class DBConnector(Pyro.core.ObjBase):
	def __init__(self):
		Pyro.core.ObjBase.__init__(self)
	
	def connect(self):
		self.connection = psycopg2.connect(host="localhost", port=5432, user="xxx",
                                           password="xxx", database="xxx")
		return self.getProxy()
	
	def cursor(self):
		print "cur"
		self.cursor = self.connection.cursor()
		return self.getProxy()
	
	def execute(self, sql, args=None):
		try:
			self.cursor.execute(sql, args)
		except:
			pass
		
	def commit(self):
		self.connection.commit()

Client:

Code: Alles auswählen

connector = uri.getProxy()
connection = connector.connect()

cursor = connection.cursor()
cursor.execute("INSERT INTO test VALUES (5, 'testing')")
connection.commit()

cursor = connection.cursor()
cursor.execute("INSERT INTO test VALUES (5, 'testing')")
connection.commit()
Beim zweiten Aufruf von connection.cursor() bekomme ich folgende Fehlermeldung.

Code: Alles auswählen

  File "G:\E-Konst\!ServiceTool\dbRemote\client.py", line 17, in <module>
    cursor = connection.cursor()
  File "G:\E-Konst\!ServiceTool\dbRemote\Pyro\core.py", line 392, in __call__
    return self.__send(self.__name, args, kwargs)
  File "G:\E-Konst\!ServiceTool\dbRemote\Pyro\core.py", line 462, in _invokePYRO
    return self.adapter.remoteInvocation(name, Pyro.constants.RIF_VarargsAndKeywords, vargs, kargs)
  File "G:\E-Konst\!ServiceTool\dbRemote\Pyro\protocol.py", line 429, in remoteInvocation
    return self._remoteInvocation(method, flags, *args)
  File "G:\E-Konst\!ServiceTool\dbRemote\Pyro\protocol.py", line 529, in _remoteInvocation
    answer.raiseEx()
  File "G:\E-Konst\!ServiceTool\dbRemote\Pyro\errors.py", line 72, in raiseEx
    raise self.excObj
TypeError: 'psycopg2._psycopg.cursor' object is not callable
Erstaunlicherweise wird die Methode cursor() des Remote Objekts nur beim ersten Mal aufgerufen (Der String "cur" wird nur einmal ausgegeben). Die Fehlermeldung kommt also nicht von dieser Methode.
Ich bin ratlos...
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Hallo!

Du überschreibst das Attribut `cursor` in Zeile 13; deswegen wird die Methode nur einmal aufgerufen. Beim zweiten Mal wird dann versucht, das Cursor-Objekt aufzurufen, und das funktioniert nicht ;)

Gruß,

Fred
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Werd aus deiner Erklärung leider nicht schlau... :?:
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Code: Alles auswählen

    def cursor(self):
        print "cur"
        self.cursor = self.connection.cursor() # <- hier.
        return self.getProxy() 
Dort setzt du self.cursor. self.cursor war vorher die Methode `cursor`. In dieser Zeile überschreibst du aber self.cursor. Wenn du dann connection.cursor aufrufst, rufst du nicht mehr die Methode auf, weil connection.cursor nicht mehr die Methode `cursor` ist, sondern der Wert von self.connection.cursor().
Methoden und andere Attribute sind also in dieser Hinsicht nicht 'getrennt'!

Ist das nun verständlicher? Wenn nicht, dann versuchts besser nochmal jemand anders ;)
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Nehmen wir mal an, du erstellst in der Klasse `Foo` eine Methode `blubb`. Diese soll in unserem Beispiel 1+1 zurückgeben:

Code: Alles auswählen

class Foo:
    def blubb(self):
        return 1+1
Wenn du jetzt aber (egal von wo) den Namen `blubb` überschreibst (das heißt, wenn du z.B. dem "Namen eine neue Variable zuweist"), dann ist `Foo.blubb` nicht mehr das, was es vorher war (eine Methode, die 1+1 zurück gibt), sondern das, zu was du es gesetzt hast (z.B. den Wert "42").

Code: Alles auswählen

class Foo:
    def blubb(self):
        return 1+1

instance = Foo()
instance.blubb() # hier ist instance.blubb eine Funktion
instance.blubb = 42 # jetzt wird instance.blubb der Wert 42 zugewiesen. Es "ist" damit keine Funktion mehr (!)
instance.blubb()
# schlägt fehl, weil blubb jetzt eine Variable ist, die den Integer-Wert "42" repräsentiert,
# und Integers (Zahlen) kann man nicht aufrufen (ausführen).
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Ach natürlich^^
Jetzt war ich ewig da dran, hatte das irgendwie für ein größeres Problem gehalten und gar nicht auf so etwas geachtet...
Antworten