11

I've mostly used argparse for making command-line scripts in python, and the idiom I generally use is that I assign the arguments as attributes of an object, then parse them individually to a variable that matches their attribute name. This seems a little repetitive. Is there a way to assign them all into the global namespace and cut out the assignment step; or as is often the case when some python behavior seems counter-intuitive to me, can some wise, python expert point out that there a good reason I should not do this or want to do this?

What I have now is this:

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--db",type=str, dest='db', nargs='?', default="test")
    parser.add_argument("--collection",type=str, dest='collection', nargs='?', help="Collection, default is test", default="test")
    args = parser.parse_args()
    db = args.db                   # gross! 
    collection = args.collection   # yuck!
    print(db)
    print(collection)

What I'd like this is:

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--db",type=str, dest='db', nargs='?', default="test")
    parser.add_argument("--collection",type=str, dest='collection', nargs='?', help="Collection, default is test", default="test")
    parser.SUPER_parse_args() # now, db and collection are already in the namespace!
    print(db)
    print(collection)

It doesn't seem like much when I only have 2 arguments, but if I have 10 or so, doubling the assign steps, where I rename into the global namespace the attributes that already exist in the args object, starts to bug me.

2
  • 6
    Don't. Just don't. I'd use args directly instead. Commented Oct 10, 2013 at 15:13
  • 1
    @MartijnPieters, you were precisely one of the wise python experts I was hoping would weigh in on this. Commented Oct 11, 2013 at 16:53

3 Answers 3

11

You can do this using globals:

globals().update(args.__dict__)

however, you really *shouldn't do that. From the zen of python,

Namespaces are one honking great idea -- let's do more of those!

I'll echo what @Martijn said in his comment:

Don't. Just don't. I'd use args directly instead.

Keep things as nicely separated as you can. It makes for more maintainable and easier to understand code.

Sign up to request clarification or add additional context in comments.

2 Comments

I see. Cool, thanks. Is the rationale for this just that having variables defined globally, and outside of args, means it's more likely to collide with new things? If so, is updating globals like this really any worse than the simple one-off python script where variables are defined in the global scope anyway? Is the idea that small scripts inevitably turn into big scripts that need smarter namespace management?
@Mittenchops -- That's part of it. It also makes the source a lot easer to read. 3 months later, when you need to update your script and you see yourself using a variable foo, but when you try to grep the source, foo isn't defined anywhere, then you start to scratch your head and wonder how the whole thing works.
0

To add onto mgilson's answer:

Consider using locals().update(args.__dict__) instead; this will update the current namespace rather than the global namespace.

You can also do this using locals() or vars(). See this Stack Overflow post for a nice explanation on the difference between the two.

I'm a bit late for Mittonchops, but hopefully this helps others.

1 Comment

Don't use locals. It won't work. :-). updating the locals dict isn't guaranteed to work on any implemention of python and doesn't work on CPython (unless you're in the globals namespace in which case locals() == globals() anyway :-)
0

This is what I did. It helps with variable collision but not maintainability.

parser_args = parser.parse_args()
if parser_args.verbose:
    globals().update(argparse.Namespace(verbose=parser_args.verbose).__dict__)

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.