This thread is an extension from the previous that can be found here. Say, I have a code that serve two purpose, 1) print a max number from a list of integer; 2) make a new dir.
import argparse
import os
parser = argparse.ArgumentParser()
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=sum,
help='sum the integers (default: find the max)')
parser.add_argument("--output_dir", type=str, default="data/xx")
def main(args):
os.makedirs(args.output_dir)
print args.accumulate(args.integers)
if __name__=='__main__':
args = parser.parse_args() # Disable during debugging @ Run through terminal
# args = argparse.Namespace(integers = 1, output_dir= 'mydata_223ss32') # Disable when run through terminal: For debugging process
main(args)
These statement can be executed from terminal by
python test_file.py --output_dir data/xxxx 2 2 5 --sum
However, for debugging process, I want to skip the usage of terminal. The idea by hpaulj as can be found from here was simply modify the
if __name__=='__main__':
into
if __name__=='__main__':
args = argparse.Namespace(output_dir= 'mydata') # Disable when run through terminal: For debugging process
main(args)
However, I also want to include a list of integer during the debugging process. Including both the list of integer and dir address as below output an error
args = argparse.Namespace(integers = "2 2 5", output_dir= 'mydata')
May I know where did I do wrong.
Thanks in advance
Go to your project properties, either by right-clicking on the project and picking "Properties" or by picking Properties from the Project menu. Click on Debug, then enter your arguments into the "Script Arguments" field. Save.
To add your arguments, use parser. add_argument() . Some important parameters to note for this method are name , type , and required . The name is exactly what it sounds like — the name of the command line field.
The store_true option automatically creates a default value of False. Likewise, store_false will default to True when the command-line argument is not present. The source for this behavior is succinct and clear: http://hg.python.org/cpython/file/2.7/Lib/argparse.py#l861.
For a more gentle introduction to Python command-line parsing, have a look at the argparse tutorial. The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv .
By slightly changing your code to:
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=sum,
help='sum the integers (default: find the max)')
parser.add_argument("--output_dir", type=str, default="data/xx")
def main(args):
#os.makedirs(args.output_dir) # XXX: Commented out for debugging
print(args.accumulate(args.integers))
if __name__=='__main__':
print(sys.argv)
args = parser.parse_args() # Disable during debugging @ Run through terminal
# args = argparse.Namespace(integers = 1, output_dir= 'mydata_223ss32') # Disable when run through terminal: For debugging process
print(args)
main(args)
We can see that if we call the script with: ./test3.py --output_dir foo 1 2 3
Our output is:
['test3.py', '--output_dir', 'foo', '1', '2', '3'] Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3], output_dir='foo') 6
So, if you want to emulate command line arguments, you have two options:
1) Edit sys.argv
(personally preferred):
if __name__=='__main__':
# Override sys.argv
sys.argv = ['test3.py', '--output_dir', 'foo', '1', '2', '3']
args = parser.parse_args()
main(args)
2) Create a Namespace
object:
if __name__=='__main__':
#args = parser.parse_args() # Disable during debugging @ Run through terminal
args = argparse.Namespace(accumulate=sum, integers=[1,2,3], output_dir='foo')
main(args)
The problem with the second approach is two-fold. First, you're skipping a very important part of the debugging process by doing this, debugging the argparse configuration and ensuring the arguments are parsed as you expect. Second, implicit defaults added by your argparse configuration must be defined here (e.g. your --sum
argument/accumulate
). If you took the first approach, argparse would process sys.argv
and add accumulate without you having to make any changes. In the second approach, we have to add accumulate=sum
for it to run as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With