-3

I have strange situation when i generate bytes with os.urandom:

import sys
import os
urand = os.urandom(1)
print(str(sys.getsizeof(urand)) + ' bytes')

Output:

34 bytes

I think its should generate 1 byte but not 34 bytes.

  • What does `len(urand)` give you…? That’s the important part. `getsizeof` includes overhead of behind-the-scenes data… – deceze Sep 24 '22 at 09:24
  • This is well explained in https://stackoverflow.com/questions/33978/find-out-how-much-memory-is-being-used-by-an-object-in-python – Nik Sep 24 '22 at 09:29

2 Answers2

1

The length of the data is one byte:

In [1]: import sys

In [2]: import os

In [3]: urand = os.urandom(1)
Out[3]: b'\x82'

In [4]: len(urand)
Out[4]: 1

Because of the dynamic nature of the language, Python has to keep a bunch of information associated with every object. This includes the type of the object:

In [5]: type(urand)
Out[5]: bytes

So that Python knows which methods can be applied to an object.

The reference count:

In [8]: sys.getrefcount(urand)
Out[8]: 9

This overhead is what you also see when you call sys.getsizeof.

It is the price we pay for a language that does a lot of housekeeping for us, like managing memory.

If you want to look at how this is implemented, start with the file Include/object.h in the Python source code.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94
0

urandom returns a bytes, which is a sequence of bytes

There is some overhead related to the sequence

>>> sys.getsizeof(os.urandom(1))
34
>>> sys.getsizeof(os.urandom(2))
35
>>> sys.getsizeof(os.urandom(12))
45

So, the overhead is 33 bytes, after which each byte in the sequence adds 1 byte.

njzk2
  • 38,969
  • 7
  • 69
  • 107