{"id":2726,"date":"2020-01-21T19:30:17","date_gmt":"2020-01-21T19:30:17","guid":{"rendered":"https:\/\/www.askpython.com\/?p=2726"},"modified":"2023-02-16T19:57:17","modified_gmt":"2023-02-16T19:57:17","slug":"python-struct-module","status":"publish","type":"post","link":"https:\/\/www.askpython.com\/python-modules\/python-struct-module","title":{"rendered":"Python struct Module"},"content":{"rendered":"\n<p>The Python struct <a href=\"https:\/\/www.askpython.com\/python-modules\" class=\"rank-math-link\">module<\/a> is used to provide a simple Pythonic interface to access and manipulate C&#8217;s structure datatype. This can be a handy tool if you ever need to deal with C code and don&#8217;t have the time to write tools in C since it is a low-level language.<\/p>\n\n\n\n<p>This module can convert Python values to a C structure and vice-versa. The C structure is used as a Python <a href=\"https:\/\/www.askpython.com\/python\/built-in-methods\/python-bytes\" class=\"rank-math-link\">bytes<\/a> object since there is nothing called an object in C; only byte-sized data structures.<\/p>\n\n\n\n<p>Let&#8217;s understand how we can use this module to have a Python interface to C structures.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Python struct Module Methods<\/h2>\n\n\n\n<p>In this module, since we are concerned with C structures, let&#8217;s look at some of the functions that this module provides us with.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">struct.pack()<\/h3>\n\n\n\n<p>This is used to pack elements into a Python byte-string (byte object). Since the mode of storage is based on bytes, C based programs can use the output of <code>pack()<\/code>, from a Python program.<\/p>\n\n\n\n<p>Format: <strong>struct.pack(format, v1, v2, &#8230;)<\/strong><\/p>\n\n\n\n<p><code>v1<\/code>, <code>v2<\/code>, &#8230; are the values which will be packed into the byte object. They represent the field values for the C structure. Since a C structure having <code>n<\/code> fields must exactly have <code>n<\/code> values, the arguments must match the values required by the format exactly.<\/p>\n\n\n\n<p>Here, <code>format<\/code> refers to the format of the packing. This is needed since we need to specify the datatype of the byte-string, as it is used with C code. The below table lists the most common values for <code>format<\/code>. We need one format per value to specify it&#8217;s datatype.<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table class=\"\"><tbody><tr><td><strong>Format<\/strong> <\/td><td><strong>C Datatype<\/strong><\/td><td><strong>Python type<\/strong><\/td><\/tr><tr><td><code>c<\/code><\/td><td>char<\/td><td>a string of length 1<\/td><\/tr><tr><td><code>?<\/code><\/td><td>_Bool<\/td><td>bool<\/td><\/tr><tr><td><code>h<\/code><\/td><td>short<\/td><td>integer<\/td><\/tr><tr><td><code>l<\/code><\/td><td>long<\/td><td>integer<\/td><\/tr><tr><td><code>i<\/code><\/td><td>int<\/td><td>integer<\/td><\/tr><tr><td><code>f<\/code><\/td><td>float<\/td><td>float<\/td><\/tr><tr><td><code>d<\/code><\/td><td>double<\/td><td>float<\/td><\/tr><tr><td><code>s<\/code><\/td><td>char[]<\/td><td>string<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Let&#8217;s understand this using some examples.<\/p>\n\n\n\n<p>The below snippet stores the 3 integers 1, 2 and 3 in a byte object using <code>pack()<\/code>. Since the size of an integer is 4 bytes on my machine, you see 3 blocks of 4 bytes, which correspond to 3 integers in C.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport struct\n\n# We pack 3 integers, so &#039;iii&#039; is required\nvariable = struct.pack(&#039;iii&#039;, 1, 2, 3)\nprint(type(variable), variable)\n\nvariable_2 = struct.pack(&#039;iic&#039;, 1, 2, b&#039;A&#039;)\nprint(&#039;\\n&#039;, variable_2)\n<\/pre><\/div>\n\n\n<p><strong>Output<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n&lt;class &#039;bytes&#039;&gt; b&#039;\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x03\\x00\\x00\\x00&#039;\nb&#039;\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00A&#039;\n<\/pre><\/div>\n\n\n<p>If the appropriate type is not passed, the exception <code>struct.error<\/code> will be raised by the Python struct module.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport struct\n\n# Error!! Incorrect datatype assignment\nvariable = struct.pack(&#039;ccc&#039;, 1, 2, 3)\nprint(type(variable), variable)\n<\/pre><\/div>\n\n\n<p><strong>Output<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nstruct.error: char format requires a bytes object of length 1\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">struct.unpack()<\/h3>\n\n\n\n<p>This function of the Python struct module, unpacks the packed value into its original representation according to an appropriate format. This returns a tuple of size equal to the number of values passed since the byte object is unpacked to give the elements.<\/p>\n\n\n\n<p>Format: <strong>struct.unpack(format, string)<\/strong><\/p>\n\n\n\n<p>This unpacks the byte <code>string<\/code> according to the <code>format<\/code> format specifier.<\/p>\n\n\n\n<p>This is the reverse of <code>struct.pack()<\/code>. Let&#8217;s take one of the old byte strings that we produced using that and try to get back the python values passed to it using <code>unpack()<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport struct\n\nbyte_str = b&#039;\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00A&#039;\n\n# Using the same format specifier as before, since\n# we want to get Python values for the same byte-string\ntuple_vals = struct.unpack(&#039;iic&#039;, byte_str)\nprint(tuple_vals)\n<\/pre><\/div>\n\n\n<p><strong>Output<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n(1, 2, b&#039;A&#039;)\n<\/pre><\/div>\n\n\n<p>As you can see, indeed, we can get pack our old Python values from this tuple, provided we use the same format specifier for both <code>pack()<\/code> and <code>unpack()<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">struct.calcsize()<\/h3>\n\n\n\n<p>This function returns the total size of the String representation of the struct using a given format specifier, to retrieve the types of the data and calculate the size.<\/p>\n\n\n\n<p>Format: <strong>struct.calcsize(fmt)<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport struct\n\nprint(&#039;C Integer Size in Bytes:&#039;, struct.calcsize(&#039;i&#039;))\nprint(&#039;Size of 3 characters in Bytes:&#039;, struct.calcsize(&#039;ccc&#039;))\n<\/pre><\/div>\n\n\n<p><strong>Output<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nC Integer Size in Bytes: 4\nSize of 3 characters in Bytes: 3\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>struct.pack_into()<\/strong><\/h3>\n\n\n\n<p>This function is used pack values into a Python string buffer, available in the <code>ctypes<\/code> module.<\/p>\n\n\n\n<p>Format: <strong>struct.pack_into(fmt, buffer, offset, v1, v2, &#8230;)<\/strong><\/p>\n\n\n\n<p>Here, <code>fmt<\/code> refers to the format specifier, as always. <code>buffer<\/code> is the string buffer which will now contain the packed values, specified. You can also specify an <code>offset<\/code> location from the base address from which packing will occur.<\/p>\n\n\n\n<p>This does not return any value, and simply stores the values into the <code>buffer<\/code> string.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport struct \nimport ctypes \n\n# We will create a string buffer having a size\n# equal to that of a struct with &#039;iic&#039; values.\nbuf_size = struct.calcsize(&#039;iic&#039;) \n\n# Create the string buffer\nbuff = ctypes.create_string_buffer(buf_size) \n  \n# struct.pack() returns the packed data \nstruct.pack_into(&#039;iic&#039;, buff, 0, 1, 2, b&#039;A&#039;)\n\nprint(buff)\n\n# Display the contents of the buffer\nprint(buff&#x5B;:])\n<\/pre><\/div>\n\n\n<p><strong>Output<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n&lt;ctypes.c_char_Array_9 object at 0x7f4bccef1040&gt;\nb&#039;\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00A&#039;\n<\/pre><\/div>\n\n\n<p>Indeed, we get our packed values in the buffer string.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">struct.unpack_from()<\/h3>\n\n\n\n<p>Similar to <code>unpack()<\/code>, a counterpart exists for unpacking values from a buffer string. This does the reverse of <code>struct.pack_into()<\/code>.<\/p>\n\n\n\n<p>Format: <strong>struct.unpack_from(fmt, buffer, offset)<\/strong><\/p>\n\n\n\n<p>This will return a tuple of values, similar to <code>struct.unpack()<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport struct \nimport ctypes \n\n# We will create a string buffer having a size\n# equal to that of a struct with &#039;iic&#039; values.\nbuf_size = struct.calcsize(&#039;iic&#039;) \n\n# Create the string buffer\nbuff = ctypes.create_string_buffer(buf_size) \n  \n# struct.pack() returns the packed data \nstruct.pack_into(&#039;iic&#039;, buff, 0, 1, 2, b&#039;A&#039;)\n\nprint(struct.unpack_from(&#039;iic&#039;, buff, 0))\n<\/pre><\/div>\n\n\n<p><strong>Output<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n(1, 2, b&#039;A&#039;)\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>In this article, we learned about using Python struct module to deal with C-type structure objects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">References<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>JournalDev article on Python struct module<\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n","protected":false},"excerpt":{"rendered":"<p>The Python struct module is used to provide a simple Pythonic interface to access and manipulate C&#8217;s structure datatype. This can be a handy tool if you ever need to deal with C code and don&#8217;t have the time to write tools in C since it is a low-level language. This module can convert Python [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-2726","post","type-post","status-publish","format-standard","hentry","category-python-modules"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/2726","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/comments?post=2726"}],"version-history":[{"count":0,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/2726\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media?parent=2726"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/categories?post=2726"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/tags?post=2726"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}