BlackJack hat geschrieben:@am2: Falls sich Objekte serialisieren lassen, dann kann man sie auch in XML serialisieren, das ist schon richtig, aber nicht alle Objekte lassen sich serialisieren. Es gibt welche die sich gegen Introspektion ”wehren” weil der innere Zustand nicht von aussen erreicht werden kann, zum Beispiel weil der Datentyp gar nicht in Python implementiert ist und sich auf irgendwelche Ressourcen ausserhalb von Python stützt. Man landet also nicht zwangsläufig immer bei elementaren Datentypen. Um so etwas allgemein zu unterstützen würde man sich auch nicht per `__dir__`/`dir()` durch die Objekte hangeln sondern den dafür vorgesehenen Mechnanismus zum (de)serialisieren verwenden den zum Beispiel auch `pickle` verwendet.
Das wäre doch ein Ansatz, oder? Natürlich ergeben sich dadurch Einschränkungen (beispielsweise Attributinhalte, die sich nicht durchschauen lassen wollen. Welches ist den der "vorgesehene Mechanismus" für Grunddatentypen, wie Zeichenketten, Wörterbücher, Zahlen...?
BlackJack hat geschrieben:Das XML welches vom Aufruf zurückkommt und klaglos in Python-Objekte übersetzt wird ist nicht beliebig. Da sind halt die Datentypen als XML serialisiert die SOAP definiert und die werden auf Python-Objekte abgebildet damit man damit in Python arbeiten kann. Und wie so ein Objekt aussieht, also von der Struktur her, sollte einem die API-Dokumentation von dem konkreten SOAP-Aufruf verraten + die Dokumentation der verwendeten SOAP-Bibliothek die verrät wie sie SOAP-Datentypen auf Python-Datentypen abbildet. Genau wie die API-Dokumentation verrät wie die Datenstruktur aussehen muss die man als Argument übergibt.
Ja und? Das ist doch völlig unbestritten. Ich möchte mich halt nur genau EINMAL darum kümmern, der Rest sollte generisch geschehen, das und nichts anderes hätte ich gern.
BlackJack hat geschrieben:Ich verstehe echt nicht wie Du einfach so erwarten kannst das man einem sprachunabhängigen RPC-Mechanismus beliebige Objekte für einen Aufruf hinwerfen kann ohne zu schauen was dieser Aufruf überhaupt an Informationen *erwartet*. Das ist in etwa so als wenn Du eine Funktion hast die zwei Argumente für geographische Länge und Breite erwartet (``void frobnicate(double lat, double long)``) und Du beim Aufruf ein Objekt von Typ `NamedPoint` übergibst das ein Feld für den Namen und ein Feld mit einem Array drei Werten für X, Y, und Z enthält und Du irgendwie erwartest, dass irgendwo bei Compilieren oder beim Aufruf schon auf magische Weise das richtige aus diesem Objekt herausgepickt und an die beiden Argumente übergeben wird ohne dass Du das explizit zuordnen müsstest.
Das habe ich nie behauptet. Natürlich muß ein solcher Aufruf mit GENAU den richtigen Parametern gestartet werden. Und ein anderer Aufruf mit anderen Parametern. Na und? Warum soll ich mich mit so etwas trivialen beschäftigen, wie einer Methode, die ein Objekt serialisiert, das am Ende letztlich doch nur aus Zeichenketten und Zahlen, gestopft in Objekte, Tupel, Listen und Dictionaries. Eine solche Regel ist doch nicht so kompliziert zu beschreiben:
- Objekte, Wörterbücher, Listen und Tupel werden Stück für Stück serialisiert, sie haben entweder Namen (Objekte oder Wörterbücher) oder Positionen (Listen, Tupel)
- elementare Objekte (Zahlen, Zeichenketten etc.)
Jetzt sag nicht, dass Deine Phantasie nicht reicht, aus einem Objekt mit 5 Attributen, von denen eines eine Liste und eines ein Wörterbuch ist, ein "sinnvolles" XML zu machen!
BlackJack hat geschrieben:„typlose Ansatz” verstehe ich jetzt nicht. Python ist stark typsiert. Jeder Wert hat einen Typ und den kann man ermitteln. Alles was man mit dieser Information zur Übersetzungszeit machen könnte, geht doch auch zur Laufzeit.
Das schon, aber Du kannst zur Entwicklungszeit nicht wissen, was zur Laufzeit so drin stecken wird. Das bedeutet, dass Du noch universeller herangehen musst.[/quote]
BlackJack hat geschrieben:Das in den Objekten andere Objekte als die Grunddatentypen stecken kannst Du ja eben *nicht* ausschliessen, denn irgendo kommt ja zum Beispiel schon mal ein `__metadata__`-Attribut ins Spiel was offensichtlich kein Grunddatentyp ist.
Genau. Daher alles, was nicht geht, ignorieren. Natürlich, wenn ich irgendwann man genau auf dieses __metadata__ angewiesen sein sollte, muss ich an der Funktion schrauben. Aber die allgemeinen Fälle, wie oben beschrieben, könnte sie abdecken.
BlackJack hat geschrieben:Es soll ein Objekt genommen und ”den Regeln gemäss” weitergeworfen werden — da ist mir nicht klar wie die Regel aussehen. An der Stelle würde ich erwarten das Du die Regeln aufstellen musst zum Beispiel in Form einer Abbildung von Attributnamen auf Parameternamen. Das ist der Teil der bei Dir irgendwie auf magische Weise passieren soll ohne das Du Dich für die Parameternamen interessierst die eigentlich vom SOAP-Aufruf erwartet werden. Das verstehe ich nicht wo diese Magie herkommen soll.
Die Regeln zu einer solchen Serialisierung findest Du oben. Magie ist da nicht das richtige Synonym.
BlackJack hat geschrieben:Man muss natürlich nicht jedes Problem in voller Detailtiefe darstellen, aber sinnvollerweise mit genug Tiefe damit man es nachvollziehen kann. Genau daran scheitert es bei mir. Für mich klingt das bis jetzt nach: ich brauche eine Funktion die ein belibiges Python-Objekt in etwas umwandelt das man einer beliebigen SOAP-Funktion als Argument übergeben kann.
ja zu jedes beliebige python- Objekt
nein zu jede beliebige SOAP- Funktion
Stell Dir eine Funktion
FüttereSoapMitObjekt(object,soapclient) vor. Die macht - gemäß oben genannter Regeln - ein XML aus dem Objekt und wirft es dem übergebenen soap- Client zum Fraß vor. Das Ergebnis schmeißt sie zurück.
Der Aufruf erfolgt dann so:
AdresseVonLiese = FüttereSoapMitObjekt(Person, AdressClient)
Landrat = FüttereSoapMitObjekt(Landkreis, PolitikClient)
Ich müsste im Grunde nichts an der Funktion FüttereSoapMitObjekt tun. Natürlich muss ich aber Person so gestalten, dass sie zu AdressClient passt, sowie Landkreis so, dass er zu PolitClient passt.
Als Information gibt's das Python-Objekt. Die SOAP-API interessiert nicht. Das klingt für mich *offensichtlich* unmöglich. Und dann gibt es auch IMHO wiedersprüchliche Informationen. Was natürlich auch damit zusammenhängen kann das ich die vorhandenen Informationen falsch deute. Zum Beispiel denke ich es geht darum ein Python-Objekt für einen SOAP-Aufruf zu konverieren. Bibliothek ist `suds`. Das Python-Objekt hat aber ein `__metadata__`-Attribut — etwas was `suds`-Objekte haben die als *Antwort* von einem SOAP-Aufruf zurückgegeben werden. Also haben wir schon einen SOAP-Aufruf hinter uns und gar nicht mehr vor uns!?
Korrekt erkannt. Ich habe "zu Fuß" ein Objekt in ein Dictionary gewandelt, das hat suds brav in ein offensichtlich geeignetes XML umgewandelt, so dass ich eine korrekte Antwort mit einem relativ komplexen Objekt vom Webservice erhielt.
Und um mein "zu Fuß" zu verbessern, habe ich es mit diesem Objekt getestet. Theoretisch könnte dieses Objekt ja auch Eingangsdatum für einen weiteren WebService dienen.
Woher das Testobjekt kommt, ist also unerheblich.
Die Fragestellung im letzten Absatz halte ich so immer noch für unmöglich zu lösen. Wenn Du das in anderen Sprachen schon gemacht hast, dann wie denn? Und warum geht das Deiner Meinung dann nicht genau so in Python?
In Python fehlen mir einfach die Mittel. In den Borland- Sprachen gibt es RTTI, womit man das meiste realisieren kann und in VB gab es auch irgendwas, mit dem ich mich durch Objekte durchhangeln konnte.
Natürlich klappt das nur wirklich pragmatisch, wenn man mit streng hierarchischen Objekten zu tun hat. Wenn es sich um Netze handelt, braucht man natürlich komplexere Strategien.
Ich bin mir immer noch nicht sicher ob ich das Problem überhaupt richtig verstanden habe. Kann es sein, dass Du eigentlich ein viel Eingeschränkteres hast? Also zum Beispiel eine SOAP-API mit Aufrufen die nur simple, nichtzusammengesetzte Argumente haben möchte und Du Objekte hast mit simplen, nichtzusammengesetzten Datenattributen die auf diese Argumente abgebildet werden sollen, und zwar vom Namen her 1:1? Wenn der Webservice dann noch eine maschinell lesbare API-Spezifikation als WSDL hat, liesse sich *dass* Problem wahrscheinlich einfach lösen.
Vielleicht kurz etwas zum Kontext:
Ich gebe geographische Informationen an den Web- Service (derzeit simpel x,y im Gauss/Krüger- Format) und dieser gibt mir (mehr oder minder komplexe) Objekte zurück, die sich dort in der Nähe befinden. Diese Objekte können sehr unterschiedlich sein, sagen wir mal Pflanzen, Häuser und Seen. Und vielleicht will ich mal einen Baum nehmen und an einen anderen Web- Service übergeben, der mir den Wert dieses Baumes zurückgibt. Da sich das Baum- Objekt aber immer verändert, muss natürlich auch die API angepasst werden, keine Frage. Aber eigentlich muss ich meinen Code nicht ändern, weil der Baum von der selben Stelle zurückgegeben wird, der auch den zweiten WebService baut. Meine Aufgabe erschöpft sich vielleicht darin, die Summe der Werte aller Bäume in einem festgelegten Gebiet zu ermitteln. Da ist es mir völlig egal, ob der Baum ein Attribut "Anzahl der Äste" hat.
Eigentlich ist mein Problem teilweise etwas spezieller (es geht um Straßen) und teilweise etwas allgemeiner (Ich weiß im Einzelfall nicht unbedingt, was ich bekomme, ich weiß nur, wohin ich das weiterwerfen muss.
Das Ganze hat etwas mit geographischen Informationen und FME zu tun. Es geht darum, ein Netz auf ein anderes abzubilden. Dazu sind verschiedene Objekte (des wirklichen Lebens) zu berücksichtigen (wenn beispielsweise in einem Netz ein Schild an der Position 100,100 steht und im anderen an 102,98 --> Dann kann es nötig sein, zu vermitteln/zu verzerren. Es ist mir aber völlig egal, was das für ein Schild ist, wie es modelliert ist - ich will es nur identifizieren.)
Und im Moment möchte ich mir nur die Arbeit erleichtern, WebServices mit Objekten zu beschicken. Das andere ist schon in weiten Bereichen fertig und erprobt, muss aber eben auch noch universeller gemacht werden, weil ich gern "jedes beliebige Netz" damit verarbeiten will.