Versión profunda de sys.getsizeof

Quiero calcular la memoria utilizada por un objeto. sys.getsizeof es genial, pero es poco profundo (por ejemplo, llamado en una lista, no incluiría la memoria tomada por los elementos de la lista).

Me gustaría escribir una versión genérica “profunda” de sys.getsizeof . Entiendo que hay cierta ambigüedad en la definición de “profundo”; Estoy perfectamente satisfecho con la definición seguida de copy.deepcopy .

Aquí está mi primer bash:

 def get_deep_sizeof(x, level=0, processed=None): if processed is None: # we're here only if this function is called by client code, not recursively processed = set() processed.add(id(x)) mem = sys.getsizeof(x) if isinstance(x, collections.Iterable) and not isinstance(x, str): for xx in x: if id(xx) in processed: continue mem += get_deep_sizeof(xx, level+1, processed) if isinstance(x, dict): mem += get_deep_sizeof(x[xx], level+1, processed) return mem 

Sufre de dos problemas conocidos y un número desconocido de problemas desconocidos:

  • No sé cómo atravesar un contenedor genérico de una manera que capture todos los objetos vinculados. Por lo tanto, iteré utilizando y codificando el caso del diccionario (para incluir valores, y no solo las claves). Obviamente, esto no funcionará para otras clases como el diccionario.
  • Tuve que codificar la exclusión de str (que es un iterable, y sin embargo no tiene enlaces a ningún otro objeto). Nuevamente, esto se romperá si hay más objetos así.

Sospecho que usar in no es una buena idea, pero no estoy seguro de qué más hacer.

Creo que Pympler ya te ha vencido al golpe en este.

De su documentación:

 >>> from pympler.asizeof import asizeof >>> obj = [1, 2, (3, 4), 'text'] >>> asizeof(obj) 176 

Si desea un ejemplo específico, puede encontrar la fuente para un asizeof aquí .