from sys import getsizeof import types from inspect import getmembers from collections import (deque, defaultdict, Counter, OrderedDict, Iterable) types_basic = { e[1] for e in filter(lambda x: isinstance(x[1], type), getmembers(types)) } types_basic.discard(types.InstanceType) types_basic.discard(types.ObjectType) types_basic.add(type(types_basic.__str__)) types_kv = {dict, OrderedDict, defaultdict, types.DictProxyType, Counter} types_listlike = {list, set, frozenset, tuple, deque} types_basic -= types_kv types_basic -= types_listlike types_kv = tuple(types_kv) types_listlike = tuple(types_listlike) types_basic = tuple(types_basic) def get_size_of2(obj): """Non-recursive function, that takes Python object, walk through its sub-objects and return a sum of size of each pointers and basic types. """ size = 0 seen = set() stack = deque() stack.append({'name': 'root', 'type': type(obj), 'object': obj, 'size': 0}) seen.add(id(obj)) while stack: cur = stack.pop() cur['size'] = cur.setdefault('size', 0) + getsizeof(cur['object']) size += cur['size'] if isinstance(cur['object'], types_basic): seen.add(cur['object']) elif isinstance(cur['object'], types_listlike): for i, e in enumerate(list(cur['object'])): if id(e) not in seen: stack.append( { 'name': cur['name'] + '-' + str(i), 'type': type(e), 'object': e } ) seen.add(id(e)) elif isinstance(cur['object'], types_kv): for i, (k, v) in enumerate(cur['object'].items()): if id(k) not in seen: stack.append( { 'name': cur['name'] + '-k: ' + str(i), 'type': type(k), 'object': k } ) seen.add(id(k)) if id(v) not in seen: stack.append( { 'name': cur['name'] + '-v: ' + str(i), 'type': type(v), 'object': v } ) seen.add(id(v)) else: for attr in dir(cur['object']): try: o = getattr(cur['object'], attr) except AttributeError: continue if id(o) not in seen: stack.append( { 'name': cur['name'] + '.' + attr, 'type': type(o), 'object': o } ) seen.add(id(o)) return size