From: R (Chandra) Chandrasekhar on 15 Feb 2010 07:35 Dear Folks, I want to execute a command from within python using the subprocess module. Coming from a Perl background, I thought I could use variable interpolation in strings, but found that this is neither supported nor the Python way. Accordingly, I am a little at sea about how to accomplish it. I have stated what I am trying to do in the minimal example below: --- import subprocess width = 5 height = 30 colors = ['#abcdef]', '#456789'] filename = "/tmp/image.png" # I want to get the equivalent of variable interpolation in Perl # so that the command # # convert -size 5x30 gradient:#abcdef-#456789 /tmp/image.png # # is derived from the variables above # and executed by subprocess.call() or subprocess.Popen() # from within Python # # Note that the command "convert" is from the ImageMagick suite # It exists and is executable by the shell; # the remaining values are arguments. # The command has been confirmed to execute correctly. --- Thanks in advance. Chandra
From: Alf P. Steinbach on 15 Feb 2010 07:44 * R (Chandra) Chandrasekhar: > > width = 5 > height = 30 > colors = ['#abcdef]', '#456789'] > filename = "/tmp/image.png" > > # I want to get the equivalent of variable interpolation in Perl > # so that the command > # > # convert -size 5x30 gradient:#abcdef-#456789 /tmp/image.png > # > # is derived from the variables above Assuming that the extra right square bracket in 'colors' is a typo, here's one way: s = "convert -size {w}x{h} gradient:{g1}-{g2} {f}".format( w = width, h = height, g1 = colors[0], g2 = colors[1], f = filename ) Cheers & hth., - ALf
From: Peter Otten on 15 Feb 2010 08:02 R (Chandra) Chandrasekhar wrote: > I want to execute a command from within python using the subprocess > module. > > Coming from a Perl background, I thought I could use variable > interpolation in strings, but found that this is neither supported nor > the Python way. Accordingly, I am a little at sea about how to > accomplish it. 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
From: R (Chandra) Chandrasekhar on 15 Feb 2010 10:48 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(). 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. Any correction of (1) to (4) and an explanation of (5) would be most appreciated. All in all, your code is a magnificent example of wrapping the function within python. This is the first time I have seen something like this. Thank you very much. Chandra
From: John Posner on 15 Feb 2010 10:59 On 2/15/2010 7:35 AM, R (Chandra) Chandrasekhar wrote: > Dear Folks, > > I want to execute a command from within python using the subprocess module. > > Coming from a Perl background, I thought I could use variable > interpolation in strings, but found that this is neither supported Yes, it is: see the use of string.Template below. > ... nor > the Python way. That right -- it isn't the Python way. Python offers two basic alternatives. Alf already presented the use of the "new" format() method of string objects. I think "traditional" Python string formatting might be what you want in this case: colors = ['#abcdef', '#456789'] format_string = "convert -size 5x30 gradient:%s-%s /tmp/image.png" cmd_string = format_string % tuple(colors) .... or better, by making *colors* a tuple instead of a list ... colors = ('#abcdef', '#456789') format_string = "convert -size 5x30 gradient:%s-%s /tmp/image.png" cmd_string = format_string % colors As Peter demonstrated, you need to use split() on *cmd_string* when you send the command to subprocess.call(). Now if you *really* miss using Perl, try this: c1, c2 = ('#abcdef', '#456789') template = string.Template( "convert -size 5x30 gradient:$c1-$c2 /tmp/image.png") cmd_string = template.substitute(locals()) Not worth the trouble, IMHO. Refs: http://www.python.org/doc/2.5.2/lib/typesseq-strings.html http://www.python.org/doc/2.5.2/lib/node40.html HTH, John
|
Next
|
Last
Pages: 1 2 3 Prev: INDIAS FIRST CTF STYLE ETHICAL HAcKING CONTEST Next: free vacation for 2 for spring break |