"struct" --- Interpret bytes as packed binary data
**************************************************

**Πηγαίος κώδικας:** 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 ορίζει την ακόλουθη εξαίρεση και συναρτήσεις:

exception struct.error

   Εξαίρεση που γίνεται raise σε διάφορες περιπτώσεις· το όρισμα είναι
   μια συμβολοσειρά που περιγράφει το σφάλμα.

struct.pack(format, v1, v2, ...)

   Επιστρέφει ένα αντικείμενο τύπου bytes που περιέχει τις τιμές *v1*,
   *v2*, ... πακεταρισμένες σύμφωνα με τη συμβολοσειρά μορφοποίησης
   *format*. Τα ορίσματα πρέπει να ταιριάζουν ακριβώς με τις
   απαιτούμενες τιμές της μορφοποίησης.

struct.pack_into(format, buffer, offset, v1, v2, ...)

   Πακετάρει τις τιμές *v1*, *v2*, ... σύμφωνα με τη συμβολοσειρά
   μορφοποίησης *format* και γράφει τα πακεταρισμένα bytes στον
   εγγράψιμο buffer *buffer* ξεκινώντας από τη θέση *offset*.
   Σημειώστε ότι το *offset* είναι υποχρεωτικό όρισμα.

struct.unpack(format, buffer)

   Αποσυμπιέζει από τον buffer *buffer* (ο οποίος υποτίθεται έχει
   πακεταριστεί με τη μέθοδο "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)

   Αποσυμπιέζει επαναληπτικά από τον buffer *buffer* σύμφωνα με τη
   συμβολοσειρά μορφοποίησης *format*. Αυτή η συνάρτηση επιστρέφει
   έναν iterator ο οποίος θα διαβάσει κομμάτια ίδιου μεγέθους από τον
   buffer μέχρι να καταναλωθούν όλα τα περιεχόμενά του. Το μέγεθος του
   buffer σε bytes πρέπει να είναι πολλαπλάσιο του μεγέθους που
   απαιτείται από τη μορφή, όπως καθορίζεται από τη συνάρτηση
   "calcsize()".

   Κάθε επανάληψη επιστρέφει μια πλειάδα σύμφωνα με τη συμβολοσειρά
   μορφοποίησης.

   Νέο στην έκδοση 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:

  * "03 ff" σε big-endian (">")

  * "ff 03" σε little-endian ("<")

  Παράδειγμα Python:

  >>> import struct
  >>> 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). Χρησιμοποιήστε την κατάλληλη επιλογή "'<'" ή "'>'".

Σημειώσεις:

1. Το συμπλήρωμα (padding) προστίθεται αυτόματα μόνο μεταξύ διαδοχικών
   μελών της δομής. Δεν προστίθεται συμπλήρωμα στην αρχή ή στο τέλος
   της κωδικοποιημένης δομής.

2. Δεν προστίθεται συμπλήρωμα όταν χρησιμοποιείται non-native μέγεθος
   και στοίχιση, π.χ. με '<','>', '=', και '!'.

3. Για να ευθυγραμμίσετε το τέλος μιας δομής με την απαίτηση στοίχισης
   ενός συγκεκριμένου τύπου, τελειώστε τη μορφή με τον κωδικό για αυτό
   τον τύπο με πλήθος επαναλήψεων μηδέν. Δείτε Παραδείγματα.


Χαρακτήρες μορφής
-----------------

Οι χαρακτήρες μορφής έχουν την ακόλουθη σημασία· η μετατροπή μεταξύ
τιμών C και Python είναι προφανής, δεδομένων των τύπων τους. Η στήλη
'Τυπικό μέγεθος' αναφέρεται στο μέγεθος της συμπιεσμένης τιμής σε byte
όταν χρησιμοποιείται τυπικό μέγεθος· δηλαδή, όταν η συμβολοσειρά
μορφής ξεκινά με ένα από τα "'<'", "'>'", "'!'" or "'='". Όταν
χρησιμοποιείται το native μέγεθος, το μέγεθος της συμπιεσμένης τιμής
εξαρτάται από την πλατφόρμα.

+----------+----------------------------+----------------------+------------------+--------------+
| Μορφή    | Τύπος C                    | Τύπος Python         | Τυπικό μέγεθος   | Σημειώσεις   |
|==========|============================|======================|==================|==============|
| "x"      | συμπληρωματικό byte        | καμία τιμή           |                  | (7)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "c"      | char                       | bytes μήκους 1       | 1                |              |
+----------+----------------------------+----------------------+------------------+--------------+
| "b"      | signed char                | integer              | 1                | (1), (2)     |
+----------+----------------------------+----------------------+------------------+--------------+
| "B"      | unsigned char              | integer              | 1                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "?"      | _Bool                      | bool                 | 1                | (1)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "h"      | short                      | integer              | 2                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "H"      | unsigned short             | integer              | 2                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "i"      | int                        | integer              | 4                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "I"      | unsigned int               | integer              | 4                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "l"      | long                       | integer              | 4                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "L"      | unsigned long              | integer              | 4                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "q"      | long long                  | integer              | 8                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "Q"      | unsigned long long         | integer              | 8                | (2)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "n"      | "ssize_t"                  | integer              |                  | (3)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "N"      | "size_t"                   | integer              |                  | (3)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "e"      | (6)                        | float                | 2                | (4)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "f"      | float                      | float                | 4                | (4)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "d"      | double                     | float                | 8                | (4)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "s"      | char[]                     | bytes                |                  | (9)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "p"      | char[]                     | bytes                |                  | (8)          |
+----------+----------------------------+----------------------+------------------+--------------+
| "P"      | void*                      | integer              |                  | (5)          |
+----------+----------------------------+----------------------+------------------+--------------+

Άλλαξε στην έκδοση 3.3: Προστέθηκε υποστήριξη για τις μορφές "'n'" και
"'N'".

Άλλαξε στην έκδοση 3.6: Προστέθηκε υποστήριξη για τη μορφή "'e'".

Σημειώσεις:

1. The "'?'" conversion code corresponds to the _Bool type defined by
   C99. If this type is not available, it is simulated using a char.
   In standard mode, it is always represented by one byte.

2. Όταν επιχειρείται η συσκευασία ενός μη ακέραιου αριθμού
   χρησιμοποιώντας οποιονδήποτε από τους κωδικούς μετατροπής ακεραίων,
   αν το αντικείμενο διαθέτει τη μέθοδο "__index__()", τότε καλείται
   αυτή η μέθοδος για τη μετατροπή του ορίσματος σε ακέραιο πριν από
   τη συσκευασία.

   Άλλαξε στην έκδοση 3.2: Προστέθηκε η χρήση της μεθόδου
   "__index__()" για μη ακέραιους αριθμούς.

3. Οι κωδικοί μετατροπής "'n'" και "'N'" είναι διαθέσιμοι μόνο για το
   native μέγεθος (επιλεγμένο ως προεπιλογή ή με τον χαρακτήρα
   διάταξης byte "'@'"). Για το τυπικό μέγεθος, μπορείτε να
   χρησιμοποιήσετε οποιαδήποτε από τις άλλες μορφές ακέραιων που
   ταιριάζουν στην εφαρμογή σας.

4. Για τους κωδικούς μετατροπής "'f'", "'d'" και "'e'", η συσκευασμένη
   αναπαράσταση χρησιμοποιεί τη μορφή IEEE 754 binary32, binary64 ή
   binary16 (αντίστοιχα για "'f'", "'d'" ή "'e'"), ανεξάρτητα από τη
   μορφή κινητής υποδιαστολής που χρησιμοποιεί η πλατφόρμα.

5. Ο χαρακτήρας μορφοποίησης "'P'" είναι διαθέσιμος μόνο για τη φυσική
   σειρά byte (επιλεγμένη ως προεπιλογή ή με τον χαρακτήρα σειράς byte
   "'@'"). Ο χαρακτήρας σειράς byte "'='" επιλέγει τη χρήση little- ή
   big-endian σειράς με βάση το σύστημα. Το module struct δεν
   ερμηνεύει αυτό ως native σειρά, επομένως η μορφή "'P'" δεν είναι
   διαθέσιμη.

6. Ο τύπος 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 για περισσότερες πληροφορίες.

7. Κατά τη συσκευασία, το "'x'" εισάγει ένα NUL byte.

8. Ο χαρακτήρας μορφοποίησης "'p'" κωδικοποιεί ένα "Pascal string",
   δηλαδή μια μικρή συμβολοσειρά μεταβλητού μήκους αποθηκευμένη σε
   *σταθερό αριθμό byte*, που καθορίζεται από τον μετρητή. Το πρώτο
   byte που αποθηκεύεται είναι το μήκος της συμβολοσειράς ή 255, όποιο
   είναι μικρότερο. Ακολουθούν τα byte της συμβολοσειράς. Εάν η
   συμβολοσειρά που περνά στην "pack()" είναι πολύ μεγάλη (μεγαλύτερη
   από τον μετρητή μείον 1), αποθηκεύονται μόνο τα πρώτα "count-1"
   byte της συμβολοσειράς. Εάν η συμβολοσειρά είναι μικρότερη από
   "count-1", συμπληρώνεται με μηδενικά byte ώστε να χρησιμοποιηθούν
   ακριβώς τόσα byte όσα καθορίζει ο μετρητής. Σημειώστε ότι για τη
   "unpack()", ο χαρακτήρας μορφοποίησης "'p'" καταναλώνει "count"
   byte, αλλά η συμβολοσειρά που επιστρέφεται δεν μπορεί ποτέ να
   περιέχει περισσότερα από 255 byte.

9. Για το χαρακτήρα μορφοποίησης "'s'", αριθμός (count) ερμηνεύεται ως
   το μήκος των byte, και όχι ως ένας αριθμός επαναλήψεων, όπως
   συμβαίνει με άλλους χαρακτήρες μορφοποίησης. Για παράδειγμα,
   "'10s'" σημαίνει μια μοναδική συμβολοσειρά 10 byte που αντιστοιχεί
   ή προέρχεται από ένα ενιαίο byte string της Python, ενώ "'10c'"
   σημαίνει 10 ξεχωριστούς χαρακτήρες του ενός byte στοιχεία (π.χ.
   "cccccccccc") που αντιστοιχούν σε ή από δέκα διαφορετικά byte
   objects της Python. (Δείτε το Παραδείγματα για μια συγκεκριμένη
   επίδειξη της διαφοράς.) Αν δεν δοθεί αριθμός, η προεπιλεγμένη τιμή
   είναι 1. Κατά την συσκευασία (packing), η συμβολοσειρά περικόπτεται
   ή συμπληρώνεται με μηδενικά byte ώστε να ταιριάζει στο καθορισμένο
   μήκος. Κατά την αποσυσκευασία (unpacking), το αποτέλεσμα είναι
   πάντα ένα αντικείμενο bytes με ακριβώς το καθορισμένο μήκος. Ως
   ειδική περίπτωση, το "'0s'" σημαίνει μια μοναδική, κενή
   συμβολοσειρά (ενώ το "'0c'" σημαίνει 0 χαρακτήρες).

Ένας χαρακτήρας μορφοποίησης μπορεί να προηγείται από έναν ακέραιο
αριθμό επαναλήψεων. Για παράδειγμα, η συμβολοσειρά μορφοποίησης "'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:

   >>> from struct import *
   >>> 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>", line 1, 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)

   >>> from collections import namedtuple
   >>> 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'

Δείτε επίσης:

  Module "array"
     Πακεταρισμένη δυαδική αποθήκευση ομοιογενών δεδομένων.

  Module "json"
     Κωδικοποιητής και αποκωδικοποιητής JSON.

  Module "pickle"
     Σειριοποίηση αντικειμένων Python.


Εφαρμογές
=========

Υπάρχουν δύο κύριες εφαρμογές για τη χρήση του "struct": η ανταλλαγή
δεδομένων μεταξύ Python και κώδικα C μέσα σε μια εφαρμογή ή με μια
άλλη εφαρμογή που έχει μεταγλωττιστεί με τον ίδιο μεταγλωττιστή
(native formats), και η ανταλλαγή δεδομένων μεταξύ εφαρμογών που
χρησιμοποιούν μια συμφωνημένη διάταξη δεδομένων (standard formats).
Γενικά, οι συμβολοσειρές μορφής που χρησιμοποιούνται σε αυτούς τους
δύο τομείς είναι διαφορετικές.


Native Μορφές
-------------

When constructing format strings which mimic native layouts, the
compiler and machine architecture determine byte ordering and padding.
In such cases, the "@" format character should be used to specify
native byte ordering and data sizes.  Internal pad bytes are normally
inserted automatically.  It is possible that a zero-repeat format code
will be needed at the end of a format string to round up to the
correct byte boundary for proper alignment of consective chunks of
data.

Εξετάστε αυτά τα δύο απλά παραδείγματα (σε έναν 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


Κλάσεις
=======

Το module "struct" ορίζει επίσης τον ακόλουθο τύπο:

class struct.Struct(format)

   Επιστρέφει ένα νέο αντικείμενο Struct που γράφει και διαβάζει
   δυαδικά δεδομένα σύμφωνα με τη συμβολοσειρά μορφοποίησης *format*.
   Η δημιουργία ενός αντικειμένου "Struct" μια φορά και η κλήση των
   μεθόδων του είναι πιο αποδοτική από την κλήση συναρτήσεων σε
   επίπεδο module με την ίδια μορφή, καθώς η συμβολοσειρά μορφοποίησης
   μεταγλωττίζεται μόνο μία φορά.

   Σημείωση:

     The compiled versions of the most recent format strings passed to
     "Struct" and the module-level functions are cached, so programs
     that use only a few format strings needn't worry about reusing a
     single "Struct" instance.

   Τα μεταγλωττισμένα αντικείμενα 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".

      Νέο στην έκδοση 3.4.

   format

      Η συμβολοσειρά μορφής που χρησιμοποιήθηκε για τη δημιουργία
      αυτού του αντικειμένου Struct.

      Άλλαξε στην έκδοση 3.7: Ο τύπος της συμβολοσειράς μορφής είναι
      πλέον "str" αντί για "bytes".

   size

      Το υπολογισμένο μέγεθος της δομής (και κατά συνέπεια του
      αντικειμένου bytes που παράγεται από τη μέθοδο "pack()") που
      αντιστοιχεί στη "format".
