Bash-like pipes in Python

Chris Angelico rosuav at gmail.com
Wed Mar 16 15:05:00 EDT 2016


On Thu, Mar 17, 2016 at 4:04 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
> Question: Could the generators define __repr__ so you wouldn't need to
> terminate the pipeline with "List" in interactive use?

No no no no. You do NOT want __repr__ to fundamentally change the
state of the object (which it would in that case - it'd consume the
generator!). What you want instead is to change sys.displayhook, which
affects *only* interactive use:

$ python3
Python 3.6.0a0 (default:ae76a1046bb9, Mar 17 2016, 05:45:31)
[GCC 5.3.1 20160224] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, types
>>> def displayhook(obj):
...     if isinstance(obj, types.GeneratorType):
...         obj = list(obj)
...         print("(%r)" % obj)
...     else:
...         print(repr(obj))
...     __builtins__._ = obj
...
>>> def gen():
...     yield 1
...     yield 2
...     yield 5
...
>>> gen()
<generator object gen at 0x7ff541604af0>
>>> sys.displayhook = displayhook
>>> gen()
([1, 2, 5])
>>> _
[1, 2, 5]


To be properly reliable, you'd want to import this function from
another module, rather than create it interactively (imagine what
happens if you shadow the built-in 'list'); and you might want to
handle the conversion to concrete recursively (which __repr__ would
have do automatically). But it's still a *lot* safer than messing
around with repr!

(By the way, I'd really love to be able to write "def
sys.displayhook(obj):". But maybe that's more cute than truly useful.)

ChrisA



More information about the Python-list mailing list