1

arguments.py

import argparse

args = None
local_host = None


def pass_arguments():
    global args, local_host
    parser = argparse.ArgumentParser()
    parser.add_argument("host", help="Host URL", type=str, default="https://example.com")
    args = parser.parse_args()
    local_host = args.host

main.py

from arguments import *

pass_arguments()
print args.host
print local_host  # defined variable to simplify access

This results an error

    print args.host
AttributeError: 'NoneType' object has no attribute 'host'

Alternatively, I could use main.py

import arguments

arguments.pass_arguments()
print arguments.args.host
print arguments.local_host  # defined variable to simplify access

What is the best practice here?

4
  • 4
    Have pass_arguments return the args variable and avoid global variables:` args = arguments.pass_arguments()`. If you are seeking advice on how to structure your program, more information on your goals is needed. If you want to pass around the arguments, see also this SO answer Commented Sep 14, 2017 at 13:01
  • @PierredeBuyl Thanks but returning args also does not help since I wanted to use the same access method in multiple modules Commented Sep 15, 2017 at 11:01
  • You can call pass_arguments several times if needed. All it does is parse the sys.argv variables repeatedly. Commented Sep 15, 2017 at 14:38
  • @PierredeBuyl Thanks, I also learned the same. But seems like an overkill, since I only wanted to share already parsed. As a workaround, I used a class. Commented Sep 22, 2017 at 5:53

1 Answer 1

0

I wondered the same thing... and thought "singleton", but given you are intending to share arguments across modules... it makes sense if your create a base_argparse module to share a singleton via base_argparse.ArgumentParser, this can then be used as a drop in replacement for argparse.ArgumentParser.

I did try Creating a singleton in Python but it seemed like overkill. (esp. if you want to share inter module)

Do let me know if you found a better way...

File: base_argparse.py

import argparse

_singleton=None
_description=""

def ArgumentParser(description=None, *arg_l, **arg_d): 
  global _singleton, _description
  if description: 
    if _description: _description+=" & "+description
    else: _description=description
  if _singleton is None: _singleton=argparse.ArgumentParser(description=_description, *arg_l, **arg_d)
  return _singleton

File: module_x.py

import sys
import base_argparse

parser = base_argparse.ArgumentParser(description='Module_X Arguments')

parser.add_argument('-x', action="store_true", default=False)

if __name__=="__main__":
  opt_ns=parser.parse_args(sys.argv[1:])
  print opt_ns,opt_ns.x

File: module_y.py

import sys
import base_argparse

parser = base_argparse.ArgumentParser(description='Module_Y Arguments')

parser.add_argument('-y', action="store", dest="y")

if __name__=="__main__":
  opt_ns=parser.parse_args(sys.argv[1:])
  print opt_ns,opt_ns.y

File: module_z.py

import sys
import base_argparse

parser = base_argparse.ArgumentParser(description='Module_Z Arguments')

parser.add_argument('-z', action="store", dest="z", type=int)

if __name__=="__main__":
  opt_ns=parser.parse_args(sys.argv[1:])
  print opt_ns,opt_ns.z

File: test_argparse.py

import sys
import base_argparse

# in main ...
parser = base_argparse.ArgumentParser(description='Test Arguments')

# then the matching load modules
import module_x,module_y,module_z

if __name__=="__main__":

  parser.add_argument('-a', action="store_true", default=False)
  parser.add_argument('-b', action="store", dest="b")
  parser.add_argument('-c', action="store", dest="c", type=int)

  opt_ns=parser.parse_args(sys.argv[1:])
  print opt_ns,opt_ns.a,opt_ns.b,opt_ns.c,opt_ns.x,opt_ns.y,opt_ns.z

Test cases:

$ python test_argparse.py

Namespace(a=False, b=None, c=None, x=False, y=None, z=None) False None None False None None

$ python module_x.py -x

Namespace(x=True) True

$ python module_x.py -a -b 2 -c 3 -x -y 25 -z 26

usage: module_x.py [-h] [-x]
module_x.py: error: unrecognized arguments: -a -b 2 -c 3 -y 25 -z 26

$ python test_argparse.py -a -b 2 -c 3

Namespace(a=True, b='2', c=3, x=False, y=None, z=None) True 2 3 False None None

$ python test_argparse.py -x -y 25 -z 26

Namespace(a=False, b=None, c=None, x=True, y='25', z=26) False None None True 25 26

$ python test_argparse.py -a -b 2 -c 3 -x -y 25 -z 26

Namespace(a=True, b='2', c=3, x=True, y='25', z=26) True 2 3 True 25 26
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.