The one thing that's killing me in Python 3000
Python 3000 was vapourware. When the vapour condensed into liquid, it was
renamed Python 3. Right now, the only vapourware is Python4000, which may
or may not be created by Guido's heir some time in the 2020s.
is that every time I try
to print something, it seems like I get <generator object <genexpr> at
0x01BAF508>.
"Every time"? Really? Even when you print an object which isn't a
generator?
Googling only found one reference, a posting elsewhere by
one Carl Johnson (aka carlj7,
http://www.artima.com/forums/flat.jsp?forum=106&thread=211200#275387),
which apparently was never answered.
Ignoring Carl's totally pointless "mycond()" function, he apparently
wants type(iterable)(i for i in iterable) to give iterable:
it = [1, 2]
type(it)(i for i in it)
[1, 2]
But that can't work for arbitrary iterables:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot convert dictionary update sequence element #0 to a
sequence
Nor will it work for generator objects themselves:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create 'generator' instances
So Carl's suggestion can't be applied universally, it can only hold for
some iterables. It doesn't even hold for all sequences, with strings a
conspicuous example. In fact, that's what Carl is complaining about:
'<generator object <genexpr> at 0xb7ce3d24>'
He apparently would prefer str(i for i in "abc") to return "abc".
However, you seem to prefer "a,b,c" instead. So what you would prefer,
and what Carl would prefer, are different.
Either way though, there's a fatal flaw in the idea: printing an object
shouldn't consume the object, but that's what you want. Unlike a list or
a tuple, a generator is *code*, not a data type. It produces values when
and as asked. So there's no way to peek inside a generator and see the
values that it will produce, consequently, for str() to behave as you and
Carl want, it has to run the generator to completion, performing an
arbitrarily large amount of work (and perhaps, for non-terminating
generators, never finishing!) before you can print it. And then, having
printed it, the generator is now exhausted. Try to print it again, and
you'll get the empty string.
Calling list() on a generator is different: it is *designed* to exhaust
the generator. I'd be upset if print() and/or str() did the same thing.
I'd also be upset if generators looked like a string when they're not:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'generator' object has no attribute 'upper'
[...]
I've
thought about defining my own function "prnt" that wraps print and fixes
generators, but that requires me to get their type, which despite the
claims of "help(type(x for x in range(0)))" cannot be found in builtins.
How are other solving this?
I'm not "solving" this, because I don't think this is a problem that
needs solving. But if you want a custom print function, this should work:
def print(*values, **kwargs):
from builtins import print as pr
gen = type(x for x in [1,2])
values = [','.join(str(s) for s in obj) if type(obj) is gen
else obj for obj in values]
pr(*values, **kwargs)