Executing a command from within python using the subprocess module

Peter Otten __peter__ at web.de
Mon Feb 15 17:44:25 CET 2010

R (Chandra) Chandrasekhar wrote:

> Peter Otten wrote:
>> import subprocess
>> def convert(width=5, height=30, colors=['#abcdef', '#456789'],
>>             filename="tmp/image with space in its name.png"):
>>     lookup = locals()
>>     assert all("\n" not in str(s) for s in lookup.values())
>>     subprocess.call("""\
>> convert
>> -size
>> {width}x{height}
>> gradient:{colors[0]}-{colors[1]}
>> {filename}""".format(**lookup).splitlines())
>> convert()
>> Peter
> Thank you. It works. Now I need to understand why and am able to follow
> what you are doing part of the way:
> 1. Assign default values in the function definition.
> 2. Store the variables existing in the local namespace in the list lookup.
> 3. Assert that there are no newlines in the values in lookup converted
> to strings. (Why? Is this because of splitlines() later on?)


> 4. Assemble a string (array?) for the subprocess.call argument using the
>   format string syntax (section 8.1.3 et seq. of the Python
> documentation for 2.6.4). Your example works with  default option of
> shell=False for subprocess.call().

I wanted to pass the executable and its arguments as a list (a python "list" 
is called array in other languages) to avoid bothering with shell escapes. 
> 5. I am unable to decipher how you got to format(**lookup).splitlines())
> especially the **prefix part, although I guess that splitlines() is
> dishing out the arguments one by one from each line in the
> subprocess.call argument.

Given some_dict = {key1: value1, key2: value2,...}


is a shortcut for

f(key1=value1, key2=value2, ...)

with the additional twist that you do not have to know the key/value pairs 
in advance.

I introduced splitlines to avoid calling the format method on every argument 
to "convert", i. e.

def convert2(width=5, height=30, colors=['#abcdef', '#456789'],
            filename="tmp/image with space in its name.png"):
            "{width}x{height}".format(width=width, height=height),

I supected that it would look cleaner than the above, but now that I tried 
it I think convert2() is the better alternative.


More information about the Python-list mailing list