Seite 1 von 1

Pyro: Methode von RemoteObjekt nur einmal aufrufbar

Verfasst: Freitag 23. Januar 2009, 13:15
von ms4py
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...

Verfasst: Freitag 23. Januar 2009, 15:19
von fred.reichbier
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

Verfasst: Freitag 23. Januar 2009, 15:52
von ms4py
Werd aus deiner Erklärung leider nicht schlau... :?:

Verfasst: Freitag 23. Januar 2009, 18:24
von fred.reichbier

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

Verfasst: Freitag 23. Januar 2009, 20:28
von Dauerbaustelle
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).

Verfasst: Montag 26. Januar 2009, 08:14
von ms4py
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...