python argparse in separate function inside a class and calling args from init
<p>I have a question regarding passing args to variables inside <strong>init</strong></p>

<p>Here are my working version of code.</p>

<pre><code>class A:
  def __init__(self):
      self.id = args.id
      self.pw = args.pw
      self.endpoint = args.endpoint

  def B:
      ..do something..

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--id', type=str, help = 'username')
    parser.add_argument('-p', '--pw', type=str, help ='password')
    parser.add_argument('-e', '--end_point', type=str , help='end point of api')
    args = parser.parse_args()
</code></pre>

<p>The above code works, but what I am trying right now is to put all the argparse codes inside a function inside class A and assign arg to init.
I looked in the web and I couldn't find a good solution.</p>

<pre><code>class A:
  def __init__(self):
      self.id = self.parse_args(id)
      self.pw = self.parse_args(pw)
      self.endpoint = self.parse_args(endpoint)

  def B:
      ..do something..

  def parse_args(self,args):
      parser = argparse.ArgumentParser()
      parser.add_argument('-i', '--id', type=str, help = 'username')
      parser.add_argument('-p', '--pw', type=str, help ='password')
      parser.add_argument('-e', '--end_point', type=str , help='end point of api')
      return parser.parse_args(args)
</code></pre>

<p>Ok, so to be exact, I'm not sure how I should approach this problem.</p>

<p>In above example, I just called args.variable for args to work but in this case I call self.id = self.parse_args.id? </p>

<p>parse_args function return args and I also tried self.id = self.parse_args(id) and this is giving me </p>

<pre><code>  TypeError: 'builtin_function_or_method' object is not iterable
</code></pre>

<p>The part of reason why I want to separate args into a separate function is to simplify my unit test with argparse.</p>

<p>Any help will be appreciated.</p>

<p>So in the first case, you must be doing</p>

<pre><code>if __name__ ...
....
args = parser.parse_args()
a = A()
</code></pre>

<p>The <code>A.__init__</code> can see <code>args</code> because it is global.</p>

<p>I'm don't see why you'd want to make the argparse code part of <code>A</code>; you don't want it to run every time you use <code>A()</code> do you?  You could only make one set of values.</p>

<p>I think it would be test to make the <code>parse_args</code> code a method, that can be run, at will, after creating the class.</p>

<p>Here's an approach that has, I think, pretty good flexibility:</p>

<pre><code>import argparse

class A:
  def __init__(self, id=None, pw=None, endpoint=None):
      self.id = id
      self.pw = pw
      self.endpoint = endpoint

  def parse_args(self, argv=None):
      parser = argparse.ArgumentParser()
      parser.add_argument('-i', '--id', type=str, help = 'username')
      parser.add_argument('-p', '--pw', type=str, help ='password')
      parser.add_argument('-e', '--end_point', type=str , help='end point of api')
      args = parser.parse_args(argv)
      self.id = args.id
      self.pw = args.pw
      self.endpoint = args.end_point

  def __str__(self):
      return 'A(%s,...)'%self.id

if __name__ == "__main__":
    a = A()
    print(a)
    a.parse_args()
    print(a)
    b = A(id='you')
    print(b)
    b.parse_args(['--id','me'])
    print(b)
</code></pre>

<p>Values can be set during object creation, from commandline or from custom argv</p>

<pre><code>1610:~/mypy$ python stack39967787.py --id joe
A(None,...)
A(joe,...)
A(you,...)
A(me,...)
</code></pre>

<p>==================</p>

<p>My 1st method (temporarily deleted)</p>

<pre><code>class A():
    def __init__(self):
        args = self.parse_args()
        self.a = args.a
        etc
    @static_method
    def parse_args(self):
        parser = ....
        return parser.parse_args()
</code></pre>

<p>=====================</p>

<p>Your <code>class A</code> could be used as <code>Namespace</code>, letting <code>parse_args</code> update the artributes directly (it uses <code>setattr</code>.</p>

<pre><code>import argparse
class A:
  def __init__(self, id=None, pw=None, endpoint=None):
      self.id = id
      self.pw = pw
      self.endpoint = endpoint

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--id', type=str, help = 'username')
    parser.add_argument('-p', '--pw', type=str, help ='password')
    parser.add_argument('-e', '--endpoint', type=str , help='end point of api')
    args = parser.parse_args()
    print(args)

    a = A()
    parser.parse_args(namespace=a)
    print(vars(a))
</code></pre>

<p>producing:</p>

<pre><code>1719:~/mypy$ python stack39967787_1.py --id joe --pw=xxxx -e1
Namespace(endpoint='1', id='joe', pw='xxxx')
{'endpoint': '1', 'id': 'joe', 'pw': 'xxxx'}
</code></pre>

python function class argparse