简体   繁体   中英

how to pass argparse arguments to a class

I'm very new to coding in general and Python in particular. I'm trying to learn how to pass argparse arguments I have created into a class for use the right/recommend way. In addition to learning python, I'm trying to learn how to do things in an OOP manner so that learning other, OOP-type languages comes a bit easier.

So here's a sample of what I am trying to do:

import argparse

class passyourcliargstome():
    def __init__(self, whatdoiputheretogetmycliargs):
        #how do I get my cli args here?
        pass
    def otherfunctionsthatdothings():
        pass

if __name__ == '__main__':
    #grab the arguments when the script is ran
    parser = argparse.ArgumentParser(
         description='Make things happen.')
    parser.add_argument('-f', '--foo', action='store_true', default=False, help='here be dragons')
    parser.add_argument('-b', '--bar', action='store_true', default=False, help='here be more dragons')

    passyourcliargstome.otherfunctionsthatdothings()

So, I'm defining argparse arguments outside of the main class, and want to know how to get them inside the class. Is this even the right way to do it? should I just make argparse a function under my class?

Thank you in advance for any assistance, references, etc.

Edit: 11/16 2:18 EST

Note: Since I don't have enough rep to answer my own question, this is my only recourse for posting a proper answer.

Okay, it took me some doing, but I managed to piece this together. RyPeck's answers helped me in getting my arguments (something my code was missing), but then afterwards I was getting unbound method errors When I was trying to test the code. I had no idea what that meant. Did I mention that I live up to my screen name?

It didn't really click until I found and read this . Here is my working code. If anyone has anything to add to this, up to and including "You're still doing it wrong, do it this way, the right way." I'm all ears. In the meantime, thanks for your help.

import argparse

class Passyourcliargstome(object):

    def __init__(self):
        #here's how I got my args here
        self.foo = args.foo
        self.bar = args.bar
    def otherfunctionsthatdothings(self):
        print "args inside of the main class:"
        print self.foo
        print self.bar

if __name__ == '__main__':
    #grab the arguments when the script is ran
    parser = argparse.ArgumentParser(description='Make things happen.')
    parser.add_argument('-f', '--foo', action='store_true', default=False, help='here be dragons')
    parser.add_argument('-b', '--bar', action='store_true', default=False, help='here be more dragons')

    args = parser.parse_args()
    print "args outside of main:"
    print args.foo
    print args.bar

    #this was the part that I wasn't doing, creating an instance of my class.
    shell = Passyourcliargstome()
    shell.otherfunctionsthatdothings()

Running this code with no arguments prints False four times. two times outside of the class instance, two times within the class instance.

Use parser.parse_args and wrap it with vars to convert the special argparse Namespace type to a regular Python dict. In general, you want this pattern:

def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('foo')
  parser.add_argument('bar')
  args = parser.parse_args()
  args_dict = vars(args)

After that, you can pass arguments explicitly or all at once to whatever class or function will take it. For a class, it is best to write the required arguments explicitly. Like so:

class MyClass(object):
  def __init__(self, foo, bar):
    self.foo = foo
    self.bar = bar

  def Print(self):
    print self.foo
    print self.bar

Now you can put those two together like this:

import argparse

class MyClass(object):
  def __init__(self, foo, bar):
    self.foo = foo
    self.bar = bar

  def Print(self):
    print self.foo
    print self.bar

def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('foo')
  parser.add_argument('bar')
  args = parser.parse_args()
  c1 = MyClass(args.foo, args.bar)
  args_dict = vars(args)
  c2 = MyClass(**args_dict)

Both c1 and c2 will be created. Best approach, though, is to create classes explicitly, as is done with c1 .

A simple for loop can pass argument (or- set your attributes):

    args_dict = vars(self.parser.parse_args())
    # using argparse arguments as attributes of this (self) class
    for item in args_dict:
        setattr(self, item, args_dict[item])

but... maybe the elegant way would be to initialize your class with argparse and set them directly to the class by namespace:

  class Foo:
  def __init__(self)
      self.parser = ArgumentParser()
      self.parser.add_argument('-f', '--foo, default=False, action='store_true', help='foo or not?')
      self.parser.add_argument('-b', '--bar', default=0, action='store', help='set the bar')  
      self.parser.parse_args(namespace=self)

an empty input is equivalent to:

  class Foo:
  def __init__(self)
      self.foo = False
      self.bar = 0

You have to do the following after you add your arguments.

args = parser.parse_args()

If you do a print on args, you'll see that you have all the arguments in a namespace argument.

You can then access them like so -

print args.foo
print args.bar

From there, you can treat them like normal variables. See the argparse documentation for greater detail and more info.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM