hallo leute, das ist mein erstes Thema. bin neu bei python. Meine frage ist wie betreff zeigt, wie kann ich ein string-param byref weitergebe? ich habe create_string_buffer() propiert aber wenn ich neuen inhalt anlege, spring "ValueError. too long string". wrapper? bitte helft mir mit eine simplen Lösung.
danke!
muchtar
passing string byref in a method
Strings sind unveränderbar. Zudem existiert ein Konzept wie ByValue oder ByRef in der Form in Python nicht.Muchtar hat geschrieben:Meine frage ist wie betreff zeigt, wie kann ich ein string-param byref weitergebe?
Du kannst allerdings eine Liste übergeben und deren Inhalte ändern.
Hallo und willkommen im Forum!
Ich nehme mal an, dass du mit ctypes arbeitest. Da solltest du schon erwähnen. Dann ist natürlich interessant, welche Fehlermeldung du genau bekommst. Inklusive des gesamten Tracebacks. Und natürlich solltest du auch ein minimales *lauffähiges* Beispiel zeigen, welches den Fehler auch reproduziert. Beim Erstellen lösen sich die meisten Probleme dann schon von alleine.
Ich nehme mal an, dass du mit ctypes arbeitest. Da solltest du schon erwähnen. Dann ist natürlich interessant, welche Fehlermeldung du genau bekommst. Inklusive des gesamten Tracebacks. Und natürlich solltest du auch ein minimales *lauffähiges* Beispiel zeigen, welches den Fehler auch reproduziert. Beim Erstellen lösen sich die meisten Probleme dann schon von alleine.
Das Leben ist wie ein Tennisball.
danke euch beide. ich glaube ich kriege das hin mit liste. Ich kenn prolog ganz gut und es ähnlet sich mit python auch einiger maßen. Und ja das ist mein aller erste aufgabe n python. nach erstem googlen landete ich an ctypes stimmt.
Obwohl ich es mit liste machen möchte, hier ist den fall
exception war
Traceback (most recent call last):
File "C:\ws\.......Serializer.py", line 52, in myserializeInternal
xmlAsStrBuffer.value = file.read()
ValueError: string too long
Muchtar
Obwohl ich es mit liste machen möchte, hier ist den fall
Code: Alles auswählen
xmlAsStrBuffer = create_string_buffer("")
result = self.myserializeInternal(model,fileName,xmlAsStrBuffer)
Code: Alles auswählen
def myserializeInternal(model,fileName,xmlAsStrBuffer):
#...
file = open(fileName)
resize(xmlAsStrBuffer,file.__sizeof__()*5)
xmlAsStrBuffer.value = file.read()
#file.close()
xmlAsStrBuffer.value = etree.tostring(root,encoding="UTF-8")
#...
Traceback (most recent call last):
File "C:\ws\.......Serializer.py", line 52, in myserializeInternal
xmlAsStrBuffer.value = file.read()
ValueError: string too long
Muchtar
``file.__sizeof__`` liefert nicht die Größe der Datei, sondern die größe des Dateiobjekts. Am einfachsten bekommst du es gelöst, wenn du deinen Code etwas umstellst:
Verändere nicht immer ein Objekt, erstelle einfach immer neue. Außerdem solltest du mal einen Blick in PEP 8 werfen, dann kannst du deinen Code näher am Standard halten.
Code: Alles auswählen
with open(filename) as fp:
string_buffer = ctypes.create_string_buffer(fp.read())
Das Leben ist wie ein Tennisball.
@Muchtar: Was willst Du denn *eigentlich* machen? `ctypes` ist dazu da um mit in C geschriebenen, oder zumindest von C aus ansprechbaren Bibliotheken zu kommunizieren. Nicht um damit in reinem Python-Quelltext Zeichenketten/Byteketten in „Arrays” zu speichern.
Die Fehlermeldung sollte übrigens selbsterklärend sein: Die Datei enthält mehr Bytes als in den `ctypes`-Datentyp passen. Das sieht alles sehr komisch aus was Du da machst.
Die Fehlermeldung sollte übrigens selbsterklärend sein: Die Datei enthält mehr Bytes als in den `ctypes`-Datentyp passen. Das sieht alles sehr komisch aus was Du da machst.
Hallo BlackJack hallo EyDu,
Danke. Ich habe es mit Listen gelöst. Es ging darum dass ich ein String-param byref übergeben möchte. Was ich mache ist es, xml-serializer-funktion die None oder "failed" als Ergebniss returnt mit einem byref-param welche den Inhalt des serialisierten XML als string hält um dann außerhalb der Funktion den XML anhand ein schema zu validieren. Verzeiht mir bitte mein Deusch
Grüße,
Muchtar
Danke. Ich habe es mit Listen gelöst. Es ging darum dass ich ein String-param byref übergeben möchte. Was ich mache ist es, xml-serializer-funktion die None oder "failed" als Ergebniss returnt mit einem byref-param welche den Inhalt des serialisierten XML als string hält um dann außerhalb der Funktion den XML anhand ein schema zu validieren. Verzeiht mir bitte mein Deusch
Grüße,
Muchtar
@Muchtar: Das ist eine furchtbare API. Python ist kein C wo man einen Zeiger für das Ergebnis übergibt und den Rückgabewert für einen Fehlercode verwendet. Du solltest da nichts ”by ref” übergeben sondern einfach das XML zurückgeben. Und falls es einen Fehler gibt eine Ausnahme auslösen.
@Muchtar: ich habe die Trennung zwischen externen Library und Python bei Dir noch nicht ganz verstanden. Vielleicht, weil sie nicht existiert. Idealer Weise sollten nur direkt vor dem Aufruf von über ctypes eingebundene Funktionen die Parameter in ctypes-Variablen kopiert werden, falls nötig. Strings werden auch direkt unterstützt und passend konvertiert. Das findet in einer Wrapper-Funktion statt, die nur diesen Aufruf enthält und (außer Fehlerbehandlung) sonst keine höheren Aufgaben hat. Für Python-Funktionen gilt: Input kommt über Parameter hinein, Output über die Rückgabewerte zurück, Fehler erzeugen Exceptions. Jede Trickserei mit Listen führt zu unlesbarem und unwartbarem Code.