12

After packing an integer in a Python struct, the unpacking results in a tuple even if it contains only one item. Why does unpacking return a tuple?

>>> x = struct.pack(">i",1)

>>> str(x)
'\x00\x00\x00\x01'

>>> y = struct.unpack(">i",x)

>>> y
(1,)
techenthu
  • 152
  • 8
Jedi
  • 2,473
  • 20
  • 39
  • 2
    If the struct contains more than one item then what do you return? Generally, it's best if functions return only a single type (so the caller doesn't have to special case depending on whether there is one item or two or ...) – mgilson Jul 11 '16 at 01:27
  • I see...Is this the only/correct/Pythonic way to pack/unpack an *int*? – Jedi Jul 11 '16 at 01:28
  • 1
    In more recent python versions there is `int.from_bytes` and `int.to_bytes` – mgilson Jul 11 '16 at 01:31

2 Answers2

10

Please see doc first struct doc

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

Return a string containing the values v1, v2, ... packed according to the given format. The arguments must match the values required by the format exactly.

--

struct.unpack(fmt, string)

Unpack the string (presumably packed by pack(fmt, ...)) according to the given format. The result is a tuple even if it contains exactly one item. The string must contain exactly the amount of data required by the format (len(string) must equal calcsize(fmt)).

Because struct.pack is define as struct.pack(fmt, v1, v2, ...). It accept a non-keyworded argument list (v1, v2, ..., aka *args), so struct.unpack need return a list like object, that's why tuple.

It would be easy to understand if you consider pack as

x = struct.pack(fmt, *args)
args = struct.unpack(fmt, x)  # return *args

Example:

>>> x = struct.pack(">i", 1)
>>> struct.unpack(">i", x)
(1,)
>>> x = struct.pack(">iii", 1, 2, 3)
>>> struct.unpack(">iii", x)
(1, 2, 3)
Community
  • 1
  • 1
Mithril
  • 10,339
  • 13
  • 81
  • 121
  • Thanks for mentioning that. I should have mentioned in my question that I saw this in the docs. I'm not sure ***why*** it returns a tuple though... – Jedi Jul 11 '16 at 01:26
2

Think of a use case that loads binary data written using C language. Python won't be able to differentiate if binary data was written using a struct or using a single integer. So, I think, logically it makes sense to return tuple always, since struct pack and unpack perform conversions between Python values and C structs.

Kevin
  • 861
  • 1
  • 7
  • 14