0

I have a script a.py :

#!/usr/bin/env python

def foo(arg1, arg2):
    return int(arg1) + int(arg2)

if __name__ == "__main__":
   import sys
   print foo(sys.argv[1], sys.argv[2])`

I now want to make a script that can run the first script and write the output of a.py to a file with some arguments as well. I want to make the automate_output(src,arglist) generate some kind of an output that I can write to the outfile :

import sys

def automate_output(src,  arglist):
    return ""


def print_to_file (src, outfile, arglist):
    print "printing to file %s" %(outfile)
    out = open(outfile, 'w')
    s = open(src, 'r')

    for line in s:
        out.write(line)
    s.close()

    out.write(" \"\"\"\n Run time example: \n") 
    out.write(automate(src, arglist))
    out.write(" \"\"\"\n")
    out.close()


try: 
    src = sys.argv[1]
    outfile = sys.argv[2]
    arglist = sys.argv[3:]
    automate(src, arglist)
    print_to_file(src,outfile,arglist)  
except:
    print "error"
    #print "usage : python automate_runtime.py scriptname outfile args"

I have tried searching around, but so far I do not understand how to pass arguments by using os.system with arguments. I have also tried doing :

import a
a.main()

There I get a NameError: name 'main' is not defined

Update : I researched some more and found subprocess and I'm quite close to cracking it now it seems. The following code does work, but I would like to pass args instead of manually passing '2' and '3' src = 'bar.py' args = ('2' , '3')
proc = subprocess.Popen(['python', src, '2' , '3'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) print proc.communicate()[0]

Arnab Datta
  • 5,356
  • 10
  • 41
  • 67
  • Actually, given what you did there, you'll get an `ImportError: No module named py` due to doing `import a.py` rather than `import a`. And the reason you get the `NameError` is because the name 'main' is not defined in the module `a`. – Chris Morgan Oct 14 '11 at 03:19
  • However, I don't understand why main is not defined? I do have if __name__ == "__main__": – Arnab Datta Oct 14 '11 at 03:30
  • If you can't see what's wrong, please read the Python tutorial; if you understand it, you'll understand what's wrong here. – Chris Morgan Oct 14 '11 at 03:31
  • Use argument unpacking `Popen(['python', 'bar.py', *args])` – Sam Dolan Oct 14 '11 at 04:02
  • @sdolan: tuple unpacking doesn't work in this case, instead use `['a', 'b'] + list(args)`. – jfs Oct 14 '11 at 04:23
  • proc = subprocess.Popen(['python', src, list(args)], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) does not work either : TypeError: execv() arg2 must contain only strings – Arnab Datta Oct 14 '11 at 04:32
  • @Arnab Datta: compare: `['a', 'b'] + list(args)` and `['a', 'b', list(args)]`. Do you see the difference? – jfs Oct 14 '11 at 05:15
  • @J.F.Sebastian : yes, now I do.. no sleep for 2 days made me blind..Thanks! – Arnab Datta Oct 14 '11 at 05:31

2 Answers2

2

This is not a function, it's an if statement:

if __name__ == "__main__":
    ...

If you want a main function, define one:

import sys

def main():
   print foo(sys.argv[1], sys.argv[2])`

Then just call it if you need to:

if __name__ == "__main__":
    main()
Brendan Long
  • 53,280
  • 21
  • 146
  • 188
1

a.main() has nothing to do with if __name__=="__main__" block. The former calls a function named main() from a module, the latter executes its block if current module name is __main__ i.e., when a module is called as a script.

#!/usr/bin/env python
# a.py
def func():
    print repr(__name__)

if __name__=="__main__":
    print "as a script",
    func()

Compare a module executed as a script and a function called from the imported module:

$ python a.py
as a script '__main__'

$ python -c "import a; print 'via import',; a.func()"
via import 'a'

See section Modules in the Python tutorial.

To get output from the subprocess you could use subprocess.check_output() function:

import sys
from subprocess import check_output as qx

args = ['2', '3']
output = qx([sys.executable, 'bar.py'] + args)
print output
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • ImportError: cannot import name check_output – Arnab Datta Oct 14 '11 at 04:22
  • @Arnab Datta: `check_output()` is new in Python 2.7. On older version you could use [`cmd_output()`](http://stackoverflow.com/questions/236737/making-a-system-call-that-returns-the-stdout-output-as-a-string/236909#236909) – jfs Oct 14 '11 at 04:33