Reputation: 15
I am pretty new to python OOP, so I got some confusion.
Currently I have:
parser = argparse.ArgumentParser(description='script 1.0')
parser.add_argument('-a', '--foo', help='specify foo')
parser.add_argument('-b', '--bar', type=int, help='specify bar')
parser.add_argument('-c', '--baz', help='specify baz')
parser.add_argument('-d', '--bar2', help='bar2')
args = parser.parse_args()
foo = args.foo
bar = args.bar
baz = args.baz
bar2 = args.bar2
which works pretty well, but I wan to create a class for the whole of my script and make argparse as a class's method (is it possible at all?).
So I tried:
import argparse
....
Class Program:
def __init__(self, foo, bar, baz, bar2):
self.foo = foo
self.bar = bar
...(so on for each arg)
def main():
parser = argparse.ArgumentParser(description='script 1.0')
parser.add_argument('-a', '--foo', help='specify foo')
parser.add_argument('-b', '--bar', type=int, help='specify bar')
parser.add_argument('-c', '--baz', help='specify baz')
parser.add_argument('-d', '--bar2', help='bar2')
args = parser.parse_args()
foo = self.foo
bar = self.bar
baz = self.baz
bar2 = self.bar2
I do not think I am doing right, though. I have not found too much info about it but one post on SO which did not clarify situation to me, so I want to have opinions for my specific case
Upvotes: 1
Views: 4367
Reputation: 2528
I would do it this way:
import argparse
Class Program:
def __init__(self, foo, bar, baz, bar2):
self.foo = foo
self.bar = bar
...(so on for each arg)
def do_things():
pass
def get_args():
parser = argparse.ArgumentParser(description='script 1.0')
parser.add_argument('-a', '--foo', help='specify foo')
parser.add_argument('-b', '--bar', type=int, help='specify bar')
parser.add_argument('-c', '--baz', help='specify baz')
parser.add_argument('-d', '--bar2', help='bar2')
return parser.parse_args()
def main(args):
instance = Program(args.foo,
args.bar,
args.baz,
args.bar2)
instance.do_things()
if __name__ == '__main__':
args = get_args()
main(args)
Explanation:
Try to separate things...
Parsing the arguments is done in the get_args
function, and then pass the "args" to the main.
The main
function is in charge to initialize the object by the parameters that been passed as args
and perform some work on the object.
Upvotes: 2
Reputation: 231665
argparse
is already makes use of classes. argparse.ArgumentParser(...)
creates a parser object. parser.add_argument(...)
creates an Action
object, and puts it in a parser
list. It also returns it to your code, which may in some advanced uses be handy. parse_args()
returns a argparse.Namespace
object.
You can subclass the argparse
classes to customize their performance.
But usually you don't need to create your own parser
class - unless you need a lot of special behavior.
Here's what I'd consider to be a clean use of argparse
:
import argparse
# your code
def main(args):
foo = args.foo
# other uses of args
def other(foo, bar):
# code using values
def make_parser():
parser = argparse.ArgumentParser(description='script 1.0')
parser.add_argument('-a', '--foo', help='specify foo')
parser.add_argument('-b', '--bar', type=int, help='specify bar')
parser.add_argument('-c', '--baz', help='specify baz')
parser.add_argument('-d', '--bar2', help='bar2')
return parser
if __name__ == '__main__':
parser = make_parser()
args = parser.parse_args()
Wrapping the parser definition in a function is a good idea. In more complex cases it could be a class. But normally you only need one parser per script, so a function is enough. That function can be in the main body of the script, but actual use should be in a if __name__
block, so the script can be imported without using the parser.
This puts the args
namespace in the global environment, where is accessible to all your code. It can be passed as to your functions, or selected values can be passed:
main(args)
other(args.foo, args.bar)
foo = args.foo
do_things3(foo)
d = vars(args) # args in dictionary form
It's a good idea to write your code so it works as imported classes and/or functions, and when run as a script. The argparse
part sets values when run as a script. When imported, the importing script sets the necessary control values, possibly with its own parser
.
Upvotes: 3