מודול struct ב- Python

ה מודול מבנה ב פִּיתוֹן מאפשר לך לעבוד עם נתונים בינאריים על ידי מתן פונקציונליות להמרה בין ערכי Python ונתונים בינאריים בסגנון C. זה שימושי במיוחד כאשר עוסקים בפורמטים של קבצים בינאריים או פרוטוקולי רשת. תכונות המפתח שלו כוללות:

  • אֲרִיזָה המרת ערכי Python לנתונים בינאריים (בתים).
  • מפרקים להמיר נתונים בינאריים בחזרה לערכי Python.
  • עיצוב מחרוזות להגדיר כיצד נתונים נארזים/פורקים באמצעות קודי פורמט (למשל i עבור מספרים שלמים f עבור צפים).

שיטות ב-struct.pack()

1.Struct.pack(): זה ממיר ערכי Python לפורמט בינארי ארוז. מחרוזת הפורמט (fmt) מציינת את הפריסה של הנתונים הארוזים והערכים הבאים (v1 v2 ...) נארזים לפי פורמט זה. תַחבִּיר:

struct.pack(fmt v1 v2 ...)

  • fmt : מחרוזת פורמט המציינת כיצד הנתונים ייארזו.
  • v1 v2...: הערכים שיארזו לפי הפורמט שצוין.
Python
   import   struct   # pack values into binary   var   =   struct  .  pack  (  'hhl'     1     2     3  )   print  (  var  )   var   =   struct  .  pack  (  'iii'     1     2     3  )   print  (  var  )   

תְפוּקָה
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'  

הסבר: 'hhl' פירושו שני מספרים שלמים קצרים (h 2 בתים כל אחד) ואחריו ארוך (l בדרך כלל 4 או 8 בתים תלוי בפלטפורמה). 'iii' מארז שלושה מספרים שלמים של 4 בתים. הפלט הוא בבתים (b'') המייצגים את הקידוד הבינארי של הערכים.

2.struct.unpack(): זה ממיר נתונים בינאריים ארוזים בחזרה לערכי Python. זה לוקח מחרוזת פורמט (fmt) ומחרוזת בינארית ארוזה ומחזירה טופלה של ערכים לא ארוזים. תַחבִּיר:

struct.unpack(fmt string)

  • fmt: מחרוזת פורמט המציינת כיצד יש לפרק את הנתונים.
  • חוּט: הנתונים הבינאריים הארוזים שצריך לפרוק.
Python
   import   struct   var   =   struct  .  pack  (  '?hil'     True     2     5     445  )   print  (  var  )   tup   =   struct  .  unpack  (  '?hil'     var  )   print  (  tup  )   var   =   struct  .  pack  (  'qf'     5     2.3  )   print  (  var  )   tup   =   struct  .  unpack  (  'qf'     var  )   print  (  tup  )   

תְפוּקָה
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)  

הֶסבֵּר: דוגמה זו אורזת תחילה בוליאני (?) קצר (h) מספר שלם (i) וארוך (l) לבייטים. לאחר מכן נעשה שימוש ב-struct.unpack() כדי להמיר אותו בחזרה לערכי Python. החלק השני אורז מספר שלם ארוך ארוך (q) וצוף (f) ואז פורק אותם בחזרה. שימו לב איך 2.3 הופך ל-2.299999952... בגלל דיוק הציפה.

3. struct.calcsize(): הוא מחזיר את הגודל (בבתים) של מבנה המתאים למחרוזת הפורמט. זה מועיל לקביעת כמה מקום נדרש לאחסון נתונים ארוזים. תַחבִּיר:

struct.calcsize(fmt)

  • fmt: מחרוזת פורמט המציינת את פריסת הנתונים.
Python
   import   struct   print  (  struct  .  calcsize  (  '?hil'  ))   print  (  struct  .  calcsize  (  'qf'  ))   

תְפוּקָה
16 12  

הסבר: '?hil' דורש 16 בתים ו 'qf' צריך 12 בתים בהתאם ליישור ולפלטפורמה.

4. struct.pack_into() ו-struct.unpack_from(): שיטות אלו מאפשרות לך לארוז ולפרוק נתונים ישירות לתוך/ממאגר החל מאופסט נתון. אלה שימושיים במיוחד כאשר מתמודדים עם מאגרי זיכרון שהוקצו מראש או כאשר עובדים עם נתונים בינאריים המאוחסנים בזיכרון.

תחביר עבור struct.pack_into():

struct.pack_into(fmt buffer offset v1 v2 ...)

  • fmt: מחרוזת פורמט המציינת את פריסת הנתונים.
  • מאגר: מאגר ניתן לכתיבה (למשל ctypes.create_string_buffer).
  • offset: מיקום ההתחלה במאגר שבו מתחילה האריזה.
  • v1 v2 ...: הערכים שיש לארוז במאגר.

תחביר עבור struct.unpack_from():

struct.unpack_from(fmt buffer offset=0)

  • fmt: מחרוזת פורמט המציינת את פריסת הנתונים.
  • בַּלָם: המאגר המכיל את הנתונים הארוזים.
  • לְקַזֵז: עמדת ההתחלה מהמקום שבו מתחילה הפריקה (אופציונלי)
Python
   import   struct   import   ctypes   # Allocate buffer   size   =   struct  .  calcsize  (  'hhl'  )   buff   =   ctypes  .  create_string_buffer  (  size  )   # Pack into buffer   struct  .  pack_into  (  'hhl'     buff     0     2     2     3  )   # Unpack from buffer   res   =   struct  .  unpack_from  (  'hhl'     buff     0  )   print  (  res  )   

תְפוּקָה
(2 2 3)  

הֶסבֵּר: כאן נוצר מאגר באמצעות ctypes. struct.pack_into() מכניס את הערכים למאגר הזה בהיסט שצוין (0 במקרה זה). struct.unpack_from() ואז קורא את הנתונים בחזרה מהמאגר.

השפעת סדר הפורמט

סדר תווי הפורמט יכול לשנות את הפלט הארוז עקב ריפוד ויישור. זה משפיע הן על תוכן הבייטים והן על גודל התוצאה.

Python
   import   struct   var   =   struct  .  pack  (  'bi'     56     0x12131415  )   print  (  var  )   print  (  struct  .  calcsize  (  'bi'  ))   var   =   struct  .  pack  (  'ib'     0x12131415     56  )   print  (  var  )   print  (  struct  .  calcsize  (  'ib'  ))   

תְפוּקָה
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5  

הסבר: 'bi' (byte int) עשוי לכלול ריפוד אחרי ה-byte ואילו 'ib' (int byte) לא צריך את זה. הפרש הגודל (8 לעומת 5) מראה כיצד יישור משפיע על פריסת הזיכרון.

טיפול בשגיאות

אם נעשה שימוש בסוג הנתונים השגוי עם struct.pack() מתרחשת struct.error. השתמש ב-try-למעט כדי לטפל במקרים כאלה בבטחה.

Python
   import   struct   try  :   struct  .  pack  (  'h'     'invalid'  )   # Wrong type 'invalid' is a string but 'h' expects an integer   except   struct  .  error   as   e  :   print  (  f  'Struct Error:   {  e  }  '  )   

תְפוּקָה

 Struct Error: required argument is not an integer   

הֶסבֵּר: זה מציג טיפול בשגיאות בעת שימוש ב-struct. 'h' מצפה למספר שלם קצר אך ניתנת מחרוזת ('לא חוקית') הגורמת ל-struct.error. הבלוק try-except לוכד את השגיאה ומדפיס הודעה משמעותית.

הַפנָיָה https://docs.python.org/2/library/struct.html

צור חידון