Executing a command from within python using the subprocess module
Peter Otten
__peter__ at web.de
Mon Feb 15 11:44:25 EST 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?)
Yes.
> 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,...}
f(**some_dict)
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"):
subprocess.call([
"convert",
"-size",
"{width}x{height}".format(width=width, height=height),
"gradient:{0}-{1}".format(*colors),
filename])
I supected that it would look cleaner than the above, but now that I tried
it I think convert2() is the better alternative.
Peter
More information about the Python-list
mailing list