Snippet: The leanest Popen wrapper

Thomas Jollans t at jollybox.de
Wed Aug 3 12:39:12 EDT 2011


On 03/08/11 17:29, Phlip wrote:
> Groupies:
> 
> This is either a code snippet, if you like it, or a request for a
> critique, if you don't.
> 
> I want to call a command and then treat the communication with that
> command as an object. And I want to do it as application-specifically
> as possible. Anyone could think of a way to productize this:
> 
> def command(*cmdz):
> 
>     process = Popen( flatten(cmdz),
>                      shell= True,
>                      stdout= subprocess.PIPE,
>                      stderr= subprocess.PIPE,
>                      bufsize= 4096 )
> 
>     def line():
>         return process.stdout.readline().rstrip()
> 
>     def s():
>         while True:
>             l = line()
>             if not l:  break

This will ignore everything after a blank line. Intended?
It may be better not to use readline(), but to use the fact that it's an
iterable, and use next(process.stdout) to get each line. (and deal with
StopIteration accordingly -- or not)

>             yield l
> 
>     line.s = s
> 
>     return line
> 
> That leads to some syntactic sugar. For example, one truly demented
> way to stream in an entire block and then treat it as one big string
> is this:
> 
> print '\n'.join(command('ls').s())
> 
> The point of the command() complex is the ability to start a long
> command and then fetch out individual lines from it:
> 
> line = command('find', '../..')
> 
> print 'lines'
> print line()
> print line()
> print line()
> 
> print 'all'
> print list(line.s())
> 
> If you need different pipe abilities, such as stdin, you can trivially
> add them to the contents of command() (it's not productized on
> purpose).
> 
> So I can take the line() functor and, for example, pin it to a View
> object, or put it in another thread now, right?
> 
> --
>   Phlip
>   http://bit.ly/ZeekLand




More information about the Python-list mailing list