Глубокая версия sys.getsizeof
Я хочу вычислить память, используемую объектом. sys.getsizeof
отлично, но неглубоко (например, вызывается в списке, он не будет включать память, занятую элементами списка).
Я хотел бы написать общую "глубокую" версию sys.getsizeof
. Я понимаю, что есть некоторая двусмысленность в определении "глубокий"; я совершенно доволен определение, за которым следует copy.deepcopy
.
вот моя первая попытка:
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
он страдает от двух известные проблемы, и неизвестное количество неизвестных проблем:
- я не знаю, как пройти общий контейнер таким образом, чтобы захватить все связанные объекты. Поэтому я повторил использование
in
, и жестко закодированный случай словаря (для включения значений, а не только ключей). Очевидно, что это не будет работать для других классов, таких как dictionary. - я жесткий код исключения
str
(который является итерируемым, и еще нет ссылки на любой другой объекты.) Опять же, это сломается, если будет больше таких объектов.
Я подозреваю, что с помощью in
- это не очень хорошая идея, но я не уверен, что еще делать.