Wie wickle ich einen xmlrpc-Funktionsaufruf ein?

Ich habe einen einfachen xmlrpc Server definiert als ( server.py ):

 from SimpleXMLRPCServer import SimpleXMLRPCServer def foo(): return "foo" server = SimpleXMLRPCServer(("localhost", 1025)) server.register_introspection_functions() server.register_function(foo, 'test.foo') server.serve_forever() 

Und der Client ( client.py ) wie folgt implementiert:

 import xmlrpclib class XMLRPC(object): def __init__(self): self.xmlrpc = xmlrpclib.ServerProxy("http://localhost:1025/RPC2") def __getattr__(self, name): attr = getattr(self.xmlrpc, name) def wrapper(*args, **kwargs): result = attr(*args, **kwargs) return result return wrapper xmlrpc = XMLRPC() print xmlrpc.test.foo() 

Ich möchte jeden Anruf, der an den xmlrpc Server innerhalb der Klasse XMLRPC gemacht wird, umwickeln und ausführen. Aber das obige Arbeitsbeispiel gibt einen Fehler

 Traceback (most recent call last): File "client.py", line 20, in <module> xmlrpc.test.foo() AttributeError: 'function' object has no attribute 'foo' 

Wie mache ich diesen Code?

Zusätzliche Informationen und Einschränkungen:

  • Ich habe schon versucht, wrapper mit functools.wraps(attr) ohne functools.wraps(attr) zu wickeln. Da die Zeichenfolge attr kein Attribut attr hat, __name__ ich einen anderen Fehler
  • Ich ändere nichts, was in server.py definiert server.py .
  • Das obige Beispiel funktioniert voll.
  • Ersetzen der return wrapper durch return attr ist keine Lösung – ich muss den eigentlichen xmlrpc Aufruf im wrapper ausführen.
  • Ich brauche eine einfache Lösung ohne Drittanbieter-Bibliothek, Standard-Python-Libs sind ok.

  • Wie installiere ich xmlrpclib in python 3.4?
  • One Solution collect form web for “Wie wickle ich einen xmlrpc-Funktionsaufruf ein?”

    Sie müssen stattdessen ein abrufbares Objekt zurückgeben.

    Der XML-RPC-Proxy gibt eine Instanz eines Objekts zurück, das aufrufbar ist, aber auch überfahren werden kann. Also für xmlrpc.test.foo() , Sie xmlrpc.test in einer Funktion; Dieses Funktionsobjekt hat kein foo Attribut, da Funktionen im Allgemeinen keine solchen Attribute haben.

    Geben Sie stattdessen ein Proxy-Objekt zurück. Der __call__ Haken macht es zu einem aufrufbaren Objekt, genau wie eine Funktion wäre:

     class WrapperProxy(object): def __init__(self, wrapped): self.wrapped = wrapped def __getattr__(self, name): attr = getattr(self.wrapped, name) return type(self)(attr) def __call__(self, *args, **kw): return self.wrapped(*args, **kw) class XMLRPC(object): def __init__(self): self.xmlrpc = xmlrpclib.ServerProxy("http://localhost:1025/RPC2") def __getattr__(self, name): attr = getattr(self.xmlrpc, name) return WrapperProxy(attr) 

    Oder in ein Objekt verschmolzen:

     class XMLRPCWrapperProxy(object): def __init__(self, wrapped=None): if wrapped is None: wrapped = xmlrpclib.ServerProxy("http://localhost:1025/RPC2") self.wrapped = wrapped def __getattr__(self, name): attr = getattr(self.wrapped, name) return type(self)(attr) def __call__(self, *args, **kw): return self.wrapped(*args, **kw) 
    Python ist die beste Programmiersprache der Welt.