Reputation: 3106
In Python, if I print
different data types separated by commas, they will all act according to their __str__
(or possibly __repr__
) methods, and print out a nice pretty string for me.
I have a bunch of variables like data1, data2...
below, and I would love to get their total approximate size. I know that:
not all of the variables have a useful sys.getsizeof
(I want to know the size stored, not the size of the container.) -Thanks to Martijn Pieters
the length of each of the printed variables is a good enough size estimate for my purposes
I'd like to avoid dealing with different data types individually. Is there any way to leverage a function like print
to get the total length of data? I find it quite unlikely that something like this is not already built into Python.
>>> obj.data1 = [1, 2, 3, 4, 5]
>>> obj.data2 = {'a': 1, 'b':2, 'c':3}
>>> obj.data3 = u'have you seen my crossbow?'
>>> obj.data4 = 'trapped on the surface of a sphere'
>>> obj.data5 = 42
>>> obj.data6 = <fake a.b instance at 0x88888>
>>> print obj.data1, obj.data2, obj.data3, obj.data4, obj.data5, obj.data6
[1, 2, 3, 4, 5] {'a': 1, 'c': 3, 'b': 2} have you seen my crossbow? trapped on the surface of a sphere 42 meh
I'm looking for something like:
printlen(obj.data1, obj.data2, obj.data3, obj.data4, obj.data5, obj.data6)
109
I know most of you could write something like this, but I'm mostly asking if Python has any built-in way to do it. A great solution would show me a way to return
the string that print
prints in Python 2.7. (Something like print_r
in PHP, which I otherwise feel is wholly inferior to Python.) I'm planning on doing this programmatically with many objects that have pre-filled variables, so no writing to a temporary file or anything like that.
Thanks!
As a side-note, this question arose from a need to calculate the approximate total size of the variables in a class that is being constructed from unknown data. If you have a way to get the total size of the non-callable items in the class (honestly, the total size would work too), that solution would be even better. I didn't make that my main question because it looks to me like Python doesn't support such a thing. If it does, hooray!
Upvotes: 0
Views: 1458
Reputation: 756
"A great solution would show me a way to return the string that print prints in Python 2.7."
This is roughly what print
prints (possibly extra spaces, missing final newline):
def print_r(*args):
return " ".join((str(arg) for arg in args))
If you run in to lots of objects that aren't str
-able use safer_str
instead:
def safer_str(obj):
return str(obj) if hasattr(obj,"__str__") else repr(obj)
Upvotes: 1
Reputation: 133899
If you have an object structure and you want to know how much does it require to store it, you could also pickle
/cpickle
the object and use that number as a measure, and to also to store the data into database.
Upvotes: 0
Reputation: 4603
This should now do it correctly:
def printlen(*args):
return sum(map(len, map(str, args)))
For objects which do not support the str(obj)
function. You could replace the str
with a self made function or lambda:
def printlen(*args):
return sum(map(len, map(lambda x: str(x) if hasattr(x, '__str__') else '', args)))
Upvotes: 1
Reputation: 159
If you want the length you can use this:
printlen = lambda *x: print(sum(len(str(i)) for i in x))
usage:
printlen(obj1, obj2, ..)
Upvotes: 0
Reputation: 1121584
First of all, sys.getsizeof()
is not the method to use to determine printed size. A python object memory footprint is a poor indicator for the number of characters required to represent a python object as a string.
You are looking for len()
instead. Use a simple generator expression plus sum()
to get a total:
def printlen(*args):
if not args:
return 0
return sum(len(str(arg)) for arg in args) + len(args) - 1
The comma between expressions tells print
to print a space, so the total length print
will write to stdout
is the sum length of all string representations, plus the whitespace between the elements.
I am assuming you do not want to include the newline print
writes as well.
Demo:
>>> printlen(data1, data2, data3, data4, data5, data6)
136
Upvotes: 1