struct
— Ερμηνεία bytes ως πακετοποιημένα δυαδικά δεδομένα¶
Πηγαίος κώδικας:Lib/struct.py
Αυτό το module μετατρέπει μεταξύ τιμών της Python και δομών της C που αναπαρίστανται ως αντικείμεναbytes
της Python. Συμπαγείςformat strings περιγράφουν τις προβλεπόμενες μετατροπές από/προς τιμές της Python. Οι συναρτήσεις και τα αντικείμενα του module μπορούν να χρησιμοποιηθούν για δύο κυρίως εφαρμογές: την ανταλλαγή δεδομένων με εξωτερικές πηγές (αρχεία ή συνδέσεις δικτύου) ή τη μεταφορά δεδομένων μεταξύ της εφαρμογής Python και του επιπέδου C.
Σημείωση
Όταν δεν δίνεται χαρακτήρας προθέματος, η προεπιλεγμένη λειτουργία είναι η εγγενής (native mode). Πακετάρει ή αποσυμπιέζει δεδομένα με βάση την πλατφόρμα και τον μεταγλωττιστή με τον οποίο κατασκευάστηκε ο διερμηνέας της Python. Το αποτέλεσμα της συσκευασίας μιας δεδομένης δομής C περιλαμβάνει συμπληρωματικά bytes (pad bytes) που διατηρούν τη σωστή στοίχιση για τους εμπλεκόμενους τύπους C· παρομοίως, η στοίχιση λαμβάνεται υπόψη κατά την αποσυσκευασία. Αντίθετα, κατά την επικοινωνία δεδομένων με εξωτερικές πηγές, ο προγραμματιστής είναι υπεύθυνος για τον καθορισμό της σειράς byte και του συμπληρώματος μεταξύ των στοιχείων. ΔείτεΔιάταξη Byte, Μέγεθος και Στοίχιση για λεπτομέρειες.
Αρκετές συναρτήσεις τουstruct
(και μέθοδοι της κλάσηςStruct
) δέχονται μια παράμετροbuffer. Αυτή αναφέρεται σε αντικείμενα που υλοποιούν ταBuffer Protocol και παρέχουν είτε ένα αναγνώσιμο είτε έναν αναγνώσιμο-εγγράψιμο buffer. Οι πιο συνηθισμένοι τύποι που χρησιμοποιούνται για αυτόν τον σκοπό είναι οιbytes
καιbytearray
, αλλά πολλοί άλλοι τύποι που μπορούν να θεωρηθούν ως πίνακες bytes υλοποιούν το πρωτόκολλο buffer, επιτρέποντας την ανάγνωση/τροφοδότηση χωρίς επιπλέον αντιγραφή από ένα αντικείμενοbytes
.
Συναρτήσεις και εξαιρέσεις¶
Το module ορίζει την ακόλουθη εξαίρεση και συναρτήσεις:
- exceptionstruct.error¶
Εξαίρεση που γίνεται raise σε διάφορες περιπτώσεις· το όρισμα είναι μια συμβολοσειρά που περιγράφει το σφάλμα.
- struct.pack(format,v1,v2,...)¶
Επιστρέφει ένα αντικείμενο τύπου bytes που περιέχει τις τιμέςv1,v2, … πακεταρισμένες σύμφωνα με τη συμβολοσειρά μορφοποίησηςformat. Τα ορίσματα πρέπει να ταιριάζουν ακριβώς με τις απαιτούμενες τιμές της μορφοποίησης.
- struct.pack_into(format,buffer,offset,v1,v2,...)¶
Πακετάρει τις τιμέςv1,v2, … σύμφωνα με τη συμβολοσειρά μορφοποίησηςformat και γράφει τα πακεταρισμένα bytes στον εγγράψιμο bufferbuffer ξεκινώντας από τη θέσηoffset. Σημειώστε ότι τοoffset είναι υποχρεωτικό όρισμα.
- struct.unpack(format,buffer)¶
Αποσυμπιέζει από τον bufferbuffer (ο οποίος υποτίθεται έχει πακεταριστεί με τη μέθοδο
pack(format,...)
) σύμφωνα με την συμβολοσειρά μορφοποίησηςformat. Το αποτέλεσμα είναι μια πλειάδα, ακόμα κι αν περιέχει μόνο ένα στοιχείο. Το μέγεθος του buffer σε bytes πρέπει να ταιριάζει με το απαιτούμενο μέγεθος σύμφωνα με τη μορφή, όπως καθορίζεται από τη συνάρτησηcalcsize()
.
- struct.unpack_from(format,/,buffer,offset=0)¶
Αποσυμπιέζει από τονbuffer ξεκινώντας από τη θέσηoffset, σύμφωνα με τη συμβολοσειρά μορφοποίησηςformat. Το αποτέλεσμα είναι μια πλειάδα, ακόμα κι αν περιέχει μόνο ένα στοιχείο. Το μέγεθος του buffer σε bytes, ξεκινώντας από τη θέσηoffset, πρέπει να είναι τουλάχιστον το μέγεθος που απαιτείται από τη μορφή, όπως καθορίζεται από τη συνάρτηση
calcsize()
.
- struct.iter_unpack(format,buffer)¶
Αποσυμπιέζει επαναληπτικά από τον bufferbuffer σύμφωνα με τη συμβολοσειρά μορφοποίησηςformat. Αυτή η συνάρτηση επιστρέφει έναν iterator ο οποίος θα διαβάσει κομμάτια ίδιου μεγέθους από τον buffer μέχρι να καταναλωθούν όλα τα περιεχόμενά του. Το μέγεθος του buffer σε bytes πρέπει να είναι πολλαπλάσιο του μεγέθους που απαιτείται από τη μορφή, όπως καθορίζεται από τη συνάρτηση
calcsize()
.Κάθε επανάληψη επιστρέφει μια πλειάδα σύμφωνα με τη συμβολοσειρά μορφοποίησης.
Added in version 3.4.
- struct.calcsize(format)¶
Επιστρέφει το μέγεθος της δομής (και κατά συνέπεια του αντικειμένου bytes που παράγεται από το
pack(format,...)
) που αντιστοιχεί στη συμβολοσειρά μορφοποίησηςformat.
Συμβολοσειρές μορφοποίησης¶
Οι συμβολοσειρές μορφοποίησης περιγράφουν τη διάταξη των δεδομένων κατά την συσκευασία και αποσυσκευασία των δεδομένων. Δημιουργούνται απόformat characters, οι οποίοι καθορίζουν τον τύπο των δεδομένων που συσκευάζονται/αποσυσκευάζονται. Επιπλέον, ειδικοί χαρακτήρες ελέγχουν τηνbyte order, size and alignment. Κάθε συμβολοσειρά μορφοποίησης αποτελείται από έναν προαιρετικό χαρακτήρα πρόθεμα που περιγράφει τις συνολικές ιδιότητες των δεδομένων και έναν ή περισσότερους χαρακτήρες μορφοποίησης που περιγράφουν τις πραγματικές τιμές δεδομένων και το συμπλήρωμα.
Διάταξη Byte, Μέγεθος και Στοίχιση¶
Από προεπιλογή, οι τύποι της C αναπαρίστανται στη φυσική μορφή και διάταξη byte της μηχανής και ευθυγραμμίζονται σωστά, παραλείποντας byte γεμίσματος εάν είναι απαραίτητο (σύμφωνα με τους κανόνες που χρησιμοποιεί ο μεταγλωττιστής C). Αυτή η συμπεριφορά επιλέγεται έτσι ώστε τα byte μιας συσκευασμένης δομής να αντιστοιχούν ακριβώς στη διάταξη μνήμης της αντίστοιχης δομής της C. Το αν θα χρησιμοποιηθεί φυσική διάταξη byte και γέμισμα ή τυποποιημένες μορφές εξαρτάται από την εφαρμογή.
Εναλλακτικά, ο πρώτος χαρακτήρας της συμβολοσειράς μορφοποίησης μπορεί να χρησιμοποιηθεί για να υποδείξει τη σειρά byte, το μέγεθος και την ευθυγράμμιση των συσκευασμένων δεδομένων, σύμφωνα με το παρακάτω πίνακα:
Χαρακτήρας | Σειρά bytes | Μέγεθος | Στοίχιση |
---|---|---|---|
| native | native | native |
| native | τυπικό | κανένα |
| little-endian | τυπικό | κανένα |
| big-endian | τυπικό | κανένα |
| δίκτυο (= big-endian) | τυπικό | κανένα |
Αν ο πρώτος χαρακτήρας δεν είναι ένας από αυτούς, υποτίθεται'@'
.
Σημείωση
Ο αριθμός 1023 (0x3ff
σε δεκαεξαδική μορφή) έχει τις ακόλουθες αναπαραστάσεις σε byte:
03ff
σε big-endian (>
)ff03
σε little-endian (<
)
Παράδειγμα Python:
>>>importstruct>>>struct.pack('>h',1023)b'\x03\xff'>>>struct.pack('<h',1023)b'\xff\x03'
Η native σειρά byte είναι big-endian ή little-endian, ανάλογα με το σύστημα υποδοχής. Για παράδειγμα, οι Intel x86, AMD64 (x86-64) και Apple M1 είναι little-endian, ενώ οι IBM z και πολλές παλαιότερες αρχιτεκτονικές είναι big-endian. Χρησιμοποιήστε τη μεταβλητήsys.byteorder
για να ελέγξετε το endianness του συστήματος σας.
Το native μέγεθος και η στοίχιση καθορίζονται χρησιμοποιώντας την έκφρασηsizeof
του μεταγλωττιστή C. Αυτό συνδυάζεται πάντα με την native σειρά byte.
Το τυπικό μέγεθος εξαρτάται μόνο από τον χαρακτήρα μορφοποίησης· δείτε τον πίνακα στην ενότηταΧαρακτήρες μορφής.
Σημειώστε τη διαφορά μεταξύ του'@'
και'='
: και τα δύο χρησιμοποιούν τη native σειρά byte, αλλά το μέγεθος και η στοίχιση του τελευταίου είναι τυποποιημένα.
Η μορφή'!'
αντιπροσωπεύει τη σειρά byte του δικτύου, η οποία είναι πάντα big-endian όπως ορίζεται στοIETF RFC 1700.
Δεν υπάρχει τρόπος να δηλωθεί non-native σειρά byte (να επιβληθεί εναλλαγή byte). Χρησιμοποιήστε την κατάλληλη επιλογή'<'
ή'>'
.
Σημειώσεις:
Το συμπλήρωμα (padding) προστίθεται αυτόματα μόνο μεταξύ διαδοχικών μελών της δομής. Δεν προστίθεται συμπλήρωμα στην αρχή ή στο τέλος της κωδικοποιημένης δομής.
Δεν προστίθεται συμπλήρωμα όταν χρησιμοποιείται non-native μέγεθος και στοίχιση, π.χ. με “<”,”>”, “=”, και “!”.
Για να ευθυγραμμίσετε το τέλος μιας δομής με την απαίτηση στοίχισης ενός συγκεκριμένου τύπου, τελειώστε τη μορφή με τον κωδικό για αυτό τον τύπο με πλήθος επαναλήψεων μηδέν. ΔείτεΠαραδείγματα.
Χαρακτήρες μορφής¶
Οι χαρακτήρες μορφής έχουν την ακόλουθη σημασία· η μετατροπή μεταξύ τιμών C και Python είναι προφανής, δεδομένων των τύπων τους. Η στήλη “Τυπικό μέγεθος” αναφέρεται στο μέγεθος της συμπιεσμένης τιμής σε byte όταν χρησιμοποιείται τυπικό μέγεθος· δηλαδή, όταν η συμβολοσειρά μορφής ξεκινά με ένα από τα'<'
,'>'
,'!'
or'='
. Όταν χρησιμοποιείται το native μέγεθος, το μέγεθος της συμπιεσμένης τιμής εξαρτάται από την πλατφόρμα.
Μορφή | Τύπος C | Τύπος Python | Τυπικό μέγεθος | Σημειώσεις |
---|---|---|---|---|
| συμπληρωματικό byte | καμία τιμή | (7) | |
| char | bytes μήκους 1 | 1 | |
| signedchar | integer | 1 | (1), (2) |
| unsignedchar | integer | 1 | (2) |
| _Bool | bool | 1 | (1) |
| short | integer | 2 | (2) |
| unsignedshort | integer | 2 | (2) |
| int | integer | 4 | (2) |
| unsignedint | integer | 4 | (2) |
| long | integer | 4 | (2) |
| unsignedlong | integer | 4 | (2) |
| longlong | integer | 8 | (2) |
| unsignedlonglong | integer | 8 | (2) |
|
| integer | (3) | |
|
| integer | (3) | |
| (6) | float | 2 | (4) |
| float | float | 4 | (4) |
| double | float | 8 | (4) |
| floatcomplex | μιγαδικός | 8 | (10) |
| doublecomplex | μιγαδικός | 16 | (10) |
| char[] | bytes | (9) | |
| char[] | bytes | (8) | |
| void* | integer | (5) |
Άλλαξε στην έκδοση 3.3:Προστέθηκε υποστήριξη για τις μορφές'n'
και'N'
.
Άλλαξε στην έκδοση 3.6:Προστέθηκε υποστήριξη για τη μορφή'e'
.
Άλλαξε στην έκδοση 3.14:Προστέθηκε υποστήριξη για τις μορφές'F'
και'D'
.
Σημειώσεις:
Ο κωδικός μετατροπής
'?'
αντιστοιχεί στον τύπο_Bool που ορίζεται από τα πρότυπα C από την έκδοση C99. Σε τυπική λειτουργία, αναπαρίσταται από ένα byte.Όταν επιχειρείται η συσκευασία ενός μη ακέραιου αριθμού χρησιμοποιώντας οποιονδήποτε από τους κωδικούς μετατροπής ακεραίων, αν το αντικείμενο διαθέτει τη μέθοδο
__index__()
, τότε καλείται αυτή η μέθοδος για τη μετατροπή του ορίσματος σε ακέραιο πριν από τη συσκευασία.Άλλαξε στην έκδοση 3.2:Προστέθηκε η χρήση της μεθόδου
__index__()
για μη ακέραιους αριθμούς.Οι κωδικοί μετατροπής
'n'
και'N'
είναι διαθέσιμοι μόνο για το native μέγεθος (επιλεγμένο ως προεπιλογή ή με τον χαρακτήρα διάταξης byte'@'
). Για το τυπικό μέγεθος, μπορείτε να χρησιμοποιήσετε οποιαδήποτε από τις άλλες μορφές ακέραιων που ταιριάζουν στην εφαρμογή σας.Για τους κωδικούς μετατροπής
'f'
,'d'
και'e'
, η συσκευασμένη αναπαράσταση χρησιμοποιεί τη μορφή IEEE 754 binary32, binary64 ή binary16 (αντίστοιχα για'f'
,'d'
ή'e'
), ανεξάρτητα από τη μορφή κινητής υποδιαστολής που χρησιμοποιεί η πλατφόρμα.Ο χαρακτήρας μορφοποίησης
'P'
είναι διαθέσιμος μόνο για τη φυσική σειρά byte (επιλεγμένη ως προεπιλογή ή με τον χαρακτήρα σειράς byte'@'
). Ο χαρακτήρας σειράς byte'='
επιλέγει τη χρήση little- ή big-endian σειράς με βάση το σύστημα. Το module struct δεν ερμηνεύει αυτό ως native σειρά, επομένως η μορφή'P'
δεν είναι διαθέσιμη.Ο τύπος IEEE 754 binary16 «half precision» εισήχθη στην αναθεώρηση του 2008 του προτύπουIEEE 754 standard. Διαθέτει ένα bit προσήμου, έναν εκθέτη 5-bit και ακρίβεια 11-bit (με 10 bit αποθηκευμένα ρητά) και μπορεί να αναπαραστήσει αριθμούς μεταξύ περίπου
6.1e-05
και6.5e+04
με πλήρη ακρίβεια. Αυτός ο τύπος δεν υποστηρίζεται ευρέως από τους μεταγλωττιστές της C: σε μια τυπική μηχανή, ένας μη προσημασμένος short μπορεί να χρησιμοποιηθεί για αποθήκευση, αλλά όχι για αριθμητικές πράξεις. Δείτε τη σελίδα της Wikipedia για τηhalf-precision floating-point format για περισσότερες πληροφορίες.Κατά τη συσκευασία, το
'x'
εισάγει ένα NUL byte.Ο χαρακτήρας μορφοποίησης
'p'
κωδικοποιεί ένα «Pascal string», δηλαδή μια μικρή συμβολοσειρά μεταβλητού μήκους αποθηκευμένη σεσταθερό αριθμό byte, που καθορίζεται από τον μετρητή. Το πρώτο byte που αποθηκεύεται είναι το μήκος της συμβολοσειράς ή 255, όποιο είναι μικρότερο. Ακολουθούν τα byte της συμβολοσειράς. Εάν η συμβολοσειρά που περνά στηνpack()
είναι πολύ μεγάλη (μεγαλύτερη από τον μετρητή μείον 1), αποθηκεύονται μόνο τα πρώταcount-1
byte της συμβολοσειράς. Εάν η συμβολοσειρά είναι μικρότερη απόcount-1
, συμπληρώνεται με μηδενικά byte ώστε να χρησιμοποιηθούν ακριβώς τόσα byte όσα καθορίζει ο μετρητής. Σημειώστε ότι για τηunpack()
, ο χαρακτήρας μορφοποίησης'p'
καταναλώνειcount
byte, αλλά η συμβολοσειρά που επιστρέφεται δεν μπορεί ποτέ να περιέχει περισσότερα από 255 byte.Για το χαρακτήρα μορφοποίησης
's'
, αριθμός (count) ερμηνεύεται ως το μήκος των byte, και όχι ως ένας αριθμός επαναλήψεων, όπως συμβαίνει με άλλους χαρακτήρες μορφοποίησης. Για παράδειγμα,'10s'``σημαίνειμιαμοναδικήσυμβολοσειρά10byteπουαντιστοιχείήπροέρχεταιαπόέναενιαίοbytestringτηςPython,ενώ``'10c'
σημαίνει 10 ξεχωριστούς χαρακτήρες του ενός byte στοιχεία (π.χ.cccccccccc
) που αντιστοιχούν σε ή από δέκα διαφορετικά byte objects της Python. (Δείτε τοΠαραδείγματα για μια συγκεκριμένη επίδειξη της διαφοράς.) Αν δεν δοθεί αριθμός, η προεπιλεγμένη τιμή είναι 1. Κατά την συσκευασία (packing), η συμβολοσειρά περικόπτεται ή συμπληρώνεται με μηδενικά byte ώστε να ταιριάζει στο καθορισμένο μήκος. Κατά την αποσυσκευασία (unpacking), το αποτέλεσμα είναι πάντα ένα αντικείμενο bytes με ακριβώς το καθορισμένο μήκος. Ως ειδική περίπτωση, το'0s'
σημαίνει μια μοναδική, κενή συμβολοσειρά (ενώ το'0c'
σημαίνει 0 χαρακτήρες).Για τους χαρακτήρες μορφής
'F'
and'D'
, η πακεταρισμένη αναπαράσταση χρησιμοποιεί τη μορφή IEEE 754 binary32 και binary64 για τα στοιχεία του μιγαδικού αριθμού, ανεξάρτητα από τη μορφή κινητής υποδιαστολής που χρησιμοποιείται από την πλατφόρμα. Σημειώστε ότι οι μιγαδικοί τύποι (F
καιD
) είναι διαθέσιμοι άνευ όρων, παρά το γεγονός ότι οι μιγαδικοί τύποι αποτελούν προαιρετικό χαρακτηριστικό στη C. Όπως ορίζεται στο πρότυπο C11, κάθε μιγαδικός τύπος αναπαρίσταται από έναν πίνακα C δύο στοιχείων που περιέχει αντίστοιχα, τα πραγματικά και τα φανταστικά μέρη.
Ένας χαρακτήρας μορφοποίησης μπορεί να προηγείται από έναν ακέραιο αριθμό επαναλήψεων. Για παράδειγμα, η συμβολοσειρά μορφοποίησης'4h'
σημαίνει ακριβώς το ίδιο με'hhhh'
.
Οι χαρακτήρες κενού μεταξύ των μορφοποιήσεων αγνοούνται· ωστόσο, ένας αριθμός και η μορφή του δεν πρέπει να περιέχουν κενά.
Κατά το πακετάρισμα μιας τιμήςx
χρησιμοποιώντας μια από τις μορφές ακεραίων ('b'
,'B'
,'h'
,'H'
,'i'
,'I'
,'l'
,'L'
,'q'
,'Q'
), εάν τοx
είναι εκτός του έγκυρου εύρους για αυτήν τη μορφή, γίνεται raise μια εξαίρεσηstruct.error
.
Άλλαξε στην έκδοση 3.1:Προηγουμένως, ορισμένες από τις μορφές ακεραίων περιτύλιγαν τιμές εκτός εύρους και εμφάνιζανDeprecationWarning
αντί γιαstruct.error
.
Για το χαρακτήρα μορφής'?'
, η τιμή που επιστρέφεται είναι είτεTrue
είτεFalse
. Κατά την συσκευασία, χρησιμοποιείται η λογική τιμή του αντικειμένου-ορίσματος. Είτε 0 είτε 1 στη native ή τυπική αναπαράσταση του bool θα συσκευαστούν, και οποιαδήποτε μη μηδενική τιμή θα είναιTrue
κατά την αποσυσκευασία.
Παραδείγματα¶
Σημείωση
Τα παραδείγματα native σειράς byte (που καθορίζονται από το πρόθεμα μορφής'@'
ή την απουσία οποιουδήποτε χαρακτήρα προθέματος) ενδέχεται να μην αντιστοιχούν σε αυτά που παράγει η μηχανή του αναγνώστη, καθώς αυτό εξαρτάται από την πλατφόρμα και τον μεταγλωττιστή.
Συσκευασία και αποσυσκευασία ακεραίων τριών διαφορετικών μεγεθών, χρησιμοποιώντας διάταξη big endian:
>>>fromstructimport*>>>pack(">bhl",1,2,3)b'\x01\x00\x02\x00\x00\x00\x03'>>>unpack('>bhl',b'\x01\x00\x02\x00\x00\x00\x03')(1, 2, 3)>>>calcsize('>bhl')7
Προσπάθεια συσκευασίας ενός ακεραίου που είναι πολύ μεγάλος για το καθορισμένο πεδίο:
>>>pack(">h",99999)Traceback (most recent call last): File"<stdin>", line1, in<module>struct.error:'h' format requires -32768 <= number <= 32767
Επιδεικνύει την διαφορά μεταξύ των χαρακτήρων μορφοποίησης's'
και'c'
:
>>>pack("@ccc",b'1',b'2',b'3')b'123'>>>pack("@3s",b'123')b'123'
Τα αποσυσκευασμένα πεδία μπορούν να ονομαστούν είτε αναθέτοντάς τα σε μεταβλητές είτε περιτυλίγοντάς τα σε μια ονομασμένη πλειάδα:
>>>record=b'raymond\x32\x12\x08\x01\x08'>>>name,serialnum,school,gradelevel=unpack('<10sHHb',record)>>>fromcollectionsimportnamedtuple>>>Student=namedtuple('Student','name serialnum school gradelevel')>>>Student._make(unpack('<10sHHb',record))Student(name=b'raymond ', serialnum=4658, school=264, gradelevel=8)
Η σειρά των χαρακτήρων μορφοποίησης μπορεί να επηρεάσει το μέγεθος σε κατάσταση native λειτουργίας, καθώς το συμπλήρωμα είναι έμμεσο. Σε τυπική λειτουργία, ο χρήστης είναι υπεύθυνος για την εισαγωγή οποιασδήποτε επιθυμητού συμπληρώματος. Σημειώστε στην πρώτη κλήσηpack
παρακάτω ότι προστέθηκαν τρία μηδενικά (NUL) bytes μετά την συσκευασμένη τιμή'#'
για να ευθυγραμμιστεί ο επόμενος ακέραιος σε όριο τεσσάρων bytes. Σε αυτό το παράδειγμα, η έξοδος παράχθηκε σε έναν υπολογιστή με little endian αρχιτεκτονική:
>>>pack('@ci',b'#',0x12131415)b'#\x00\x00\x00\x15\x14\x13\x12'>>>pack('@ic',0x12131415,b'#')b'\x15\x14\x13\x12#'>>>calcsize('@ci')8>>>calcsize('@ic')5
Η ακόλουθη μορφή'llh0l'
έχει ως αποτέλεσμα την προσθήκη δύο bytes συμπλήρωσης στο τέλος, υποθέτοντας ότι οι μακροί ακέραιοι (longs) της πλατφόρμας ευθυγραμμίζονται σε όρια 4-byte:
>>>pack('@llh0l',1,2,3)b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
Εφαρμογές¶
Υπάρχουν δύο κύριες εφαρμογές για τη χρήση τουstruct
: η ανταλλαγή δεδομένων μεταξύ Python και κώδικα C μέσα σε μια εφαρμογή ή με μια άλλη εφαρμογή που έχει μεταγλωττιστεί με τον ίδιο μεταγλωττιστή (native formats), και η ανταλλαγή δεδομένων μεταξύ εφαρμογών που χρησιμοποιούν μια συμφωνημένη διάταξη δεδομένων (standard formats). Γενικά, οι συμβολοσειρές μορφής που χρησιμοποιούνται σε αυτούς τους δύο τομείς είναι διαφορετικές.
Native Μορφές¶
Όταν κατασκευάζετε συμβολοσειρές μορφοποίησης που μιμούνται native διατάξεις, ο μεταγλωττιστής και η αρχιτεκτονική του μηχανήματος καθορίζουν τη σειρά των byte και τη συμπλήρωση. Σε τέτοιες περιπτώσεις, ο χαρακτήρας μορφής@
θα πρέπει να χρησιμοποιείται για να καθορίζει την native σειρά byte και τα μεγέθη δεδομένων. Τα εσωτερικά byte συμπλήρωσης εισάγονται συνήθως αυτόματα. Είναι πιθανό να χρειαστεί ένας κωδικός μορφοποίησης με επανάληψη μηδέν στο τέλος μιας συμβολοσειράς μορφοποίησης για να ευθυγραμμιστεί σωστά με τα όρια byte των διαδοχικών τμημάτων δεδομένων.
Εξετάστε αυτά τα δύο απλά παραδείγματα (σε έναν 64-bit, little-endian υπολογιστή):
>>>calcsize('@lhl')24>>>calcsize('@llh')18
Τα δεδομένα δεν συμπληρώνονται σε όριο 8 byte στο τέλος της δεύτερης συμβολοσειράς μορφοποίησης χωρίς τη χρήση επιπλέον συμπλήρωσης. Ένας κωδικός μορφοποίησης με επανάληψη μηδέν λύνει αυτό το πρόβλημα:
>>>calcsize('@llh0l')24
Ο κωδικός μορφοποίησης'x'
μπορεί να χρησιμοποιηθεί για να καθορίσει την επανάληψη, αλλά για native μορφές είναι προτιμότερο να χρησιμοποιείται ένας κωδικός μορφοποίησης με επανάληψη μηδέν, όπως'0l'
.
Από προεπιλογή, χρησιμοποιείται η native σειρά byte και στοίχιση, αλλά είναι καλύτερο να είμαστε σαφείς και να χρησιμοποιούμε τον χαρακτήρα πρόθεμα'@'
.
Τυπικές μορφές¶
Όταν ανταλλάσετε δεδομένα πέρα από τη διεργασία σας, όπως σε δικτύωση ή αποθήκευση, να είστε ακριβείς. Καθορίστε την ακριβή σειρά των byte, το μέγεθος και την ευθυγράμμιση. Μην υποθέτετε ότι ταιριάζουν με τη φυσική σειρά μιας συγκεκριμένης μηχανής. Για παράδειγμα, η σειρά byte του δικτύου είναι big-endian, ενώ πολλοί δημοφιλείς επεξεργαστές είναι little-endian. Ορίζοντας αυτό ρητά, ο χρήστης δεν χρειάζεται να ενδιαφέρεται για τις λεπτομέρειες της πλατφόρμας στην οποία εκτελείται ο κώδικας. Ο πρώτος χαρακτήρας πρέπει τυπικά να είναι<
ή>
(ή!
). Η ευθύνη για την προσθήκη συμπληρωματικών byte ανήκει στον προγραμματιστή. Ο χαρακτήρας μορφής με μηδενική επανάληψη δεν θα λειτουργήσει. Αντ” αυτού, ο χρήστης πρέπει να προσθέτει ρητά byte'x'
όπου απαιτείται. Επανεξετάζοντας τα παραδείγματα από την προηγούμενη ενότητα, έχουμε:
>>>calcsize('<qh6xq')24>>>pack('<qh6xq',1,2,3)==pack('@lhl',1,2,3)True>>>calcsize('@llh')18>>>pack('@llh',1,2,3)==pack('<qqh',1,2,3)True>>>calcsize('<qqh6x')24>>>calcsize('@llh0l')24>>>pack('@llh0l',1,2,3)==pack('<qqh6x',1,2,3)True
Τα παραπάνω αποτελέσματα (εκτελεσμένα σε 64-bit μηχανή) δεν είναι εγγυημένο ότι θα ταιριάζουν όταν εκτελούνται σε διαφορετικές μηχανές. Για παράδειγμα, τα παρακάτω παραδείγματα εκτελέστηκαν σε 32-bit μηχανή:
>>>calcsize('<qqh6x')24>>>calcsize('@llh0l')12>>>pack('@llh0l',1,2,3)==pack('<qqh6x',1,2,3)False
Κλάσεις¶
Το modulestruct
ορίζει επίσης τον ακόλουθο τύπο:
- classstruct.Struct(format)¶
Επιστρέφει ένα νέο αντικείμενο Struct που γράφει και διαβάζει δυαδικά δεδομένα σύμφωνα με τη συμβολοσειρά μορφοποίησηςformat. Η δημιουργία ενός αντικειμένου
Struct
μια φορά και η κλήση των μεθόδων του είναι πιο αποδοτική από την κλήση συναρτήσεων σε επίπεδο module με την ίδια μορφή, καθώς η συμβολοσειρά μορφοποίησης μεταγλωττίζεται μόνο μία φορά.Σημείωση
Οι μεταγλωττισμένες εκδόσεις των πιο πρόσφατων συμβολοσειρών μορφοποίησης που περνούν στις συναρτήσεις του module αποθηκεύονται προσωρινά, επομένως τα προγράμματα που χρησιμοποιούν μόνο λίγες συμβολοσειρές μορφοποίησης δεν χρειάζεται να ανησυχούν για την επαναχρησιμοποίηση μιας μεμονωμένης περίπτωσης της κλάσης
Struct
.Τα μεταγλωττισμένα αντικείμενα Struct υποστηρίζουν τις ακόλουθες μεθόδους και ιδιότητες:
- pack(v1,v2,...)¶
Ταυτόσημο με τη συνάρτηση
pack()
, χρησιμοποιώντας τη μεταγλωττισμένη μορφή. (len(result)
θα είναι ίσο μεsize
.)
- pack_into(buffer,offset,v1,v2,...)¶
Ταυτόσημο με τη συνάρτηση
pack_into()
, χρησιμοποιώντας τη μεταγλωττισμένη μορφή.
- unpack(buffer)¶
Ταυτόσημο με τη συνάρτηση
unpack()
, χρησιμοποιώντας τη μεταγλωττισμένη μορφή. Το μέγεθος του buffer σε bytes πρέπει να είναι ίσο μεsize
.
- unpack_from(buffer,offset=0)¶
Ταυτόσημο με τη συνάρτηση
unpack_from()
, χρησιμοποιώντας τη μεταγλωττισμένη μορφή. Το μέγεθος του buffer σε bytes, ξεκινώντας από τη θέσηoffset, πρέπει να είναι τουλάχιστονsize
.
- iter_unpack(buffer)¶
Ταυτόσημο με τη συνάρτηση
iter_unpack()
, χρησιμοποιώντας τη μεταγλωττισμένη μορφή. Το μέγεθος του buffer σε bytes πρέπει να είναι πολλαπλάσιο τουsize
.Added in version 3.4.
- format¶
Η συμβολοσειρά μορφής που χρησιμοποιήθηκε για τη δημιουργία αυτού του αντικειμένου Struct.
- size¶
Το υπολογισμένο μέγεθος της δομής (και κατά συνέπεια του αντικειμένου bytes που παράγεται από τη μέθοδο
pack()
) που αντιστοιχεί στηformat
.
Άλλαξε στην έκδοση 3.13:Ηrepr() αναπαράσταση των δομών έχει αλλάξει. Είναι πλέον:
>>>Struct('i')Struct('i')