Ich möchte benutzen struct.unpack()
Um einen langen Wert aus einer Byte-Zeichenfolge in Python 2.7 zu erhalten, habe ich ein merkwürdiges Verhalten festgestellt und möchte wissen, ob dies ein Fehler ist oder nicht und was ich tun kann, um ihn zu umgehen.
Was passiert, ist folgendes:
import struct
>>> struct.unpack("L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 8
Dies ist das erwartete Verhalten. Es wird eine 8-Byte-Zeichenfolge benötigt, um den 8-Byte-langen Wert zu extrahieren.
Jetzt ändere ich die Bytereihenfolge in Netzwerk-Bytereihenfolge und erhalte Folgendes:
>>> struct.unpack("!L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 4
Plötzlich werden nur 4 Byte für den 8 Byte langen Wert benötigt.
Was ist damit los und was kann ich tun, um das zu umgehen?
Antworten:
1 für die Antwort № 1Das Problem ist, dass struct
verwendet die native Ihres Computers long
Größe im ersten Fall und struct
"s" Standard long
Größe in der Sekunde.
Im ersten Beispiel geben Sie kein an Bezeichner für Byte-Reihenfolge, Größe und Ausrichtung (einer von @=<>!
) so struct
geht davon aus "@"
, der die nativen Werte Ihres Computers verwendet, nämlich die nativen Werte Ihres Computers long
Größe. Um plattformübergreifend konsistent zu sein, struct
definiert Standardgrößen für jeden Typ, die von den nativen Größen Ihrer Maschine abweichen können. Jeder Spezifizierer außer "@"
verwendet diese Standardgrößen.
Also im Fall von long
, struct
"s Standard ist 4 Bytes, weshalb "!L"
(oder irgendein "[=<>!]L"
erwartet 4 Bytes. Ihre Maschine ist jedoch native long
ist anscheinend 8 Bytes, weshalb "@L"
oder "L"
Erwartet 8. Wenn Sie die native Bytereihenfolge Ihres Computers verwenden möchten, aber immer noch kompatibel mit struct
"s Standardgrößen würde ich empfehlen, dass Sie alle Formate mit angeben "="
, anstatt Python standardmäßig verwenden zu lassen "@"
.
Sie können die Größenerwartung mit überprüfen struct.calcsize
, d.h.
>>> struct.calcsize("@L"), struct.calcsize("=L")
(Dies kehrt zurück (4, 4)
auf meinem 64-bit Windows 10 Rechner, aber (8, 4)
auf meinem 64-bit Ubuntu 16.04 Rechner.)
Sie können die Typgröße Ihrer Maschine auch direkt überprüfen, indem Sie a kompilieren C
Skript, um den Wert von zu überprüfen sizeof(long)
, beispielsweise:
#include <stdio.h>
int main()
{
printf("%li",sizeof(long));
return 0;
}
ich folgte dieser Leitfaden um das zu kompilieren C
Skript auf meinem Windows 10-Computer.