3

Say I have a namespace args that I obtain from calling parser.parse_args(), which parses the command line arguments.

How can I import all variables from this namespace to my current namespace?

e.g.

parser.add_argument('-p', '--some_parameter', default=1)

args = parser.parse_args()

# ... code to load all variables defined in the namespace args ...

print some_parameter

I could certainly do:

some_parameter = args.some_parameter

but if I have a large number of parameters I would need one such line for each parameter.

Is there another way of importing variables from a namespace without having to go through them one by one?

PS: from args import * does not work.

PS2: I am aware that this is a bad practice, but this can help in some corner cases, such us when prototyping code and tests very quickly.

4
  • You could loop over __dict__ or use inspect... Commented Feb 4, 2013 at 22:47
  • 1
    Or just locals().update(namespace._get_kwargs()). Commented Feb 4, 2013 at 22:51
  • 2
    Why do you want to do this? Why not just access args.some_parameter? (Especially since, in a non-trivial program, you're probably going to want to pass the options to other functions, which means if you've got lots of options you're probably going to end up building a dict or other object equivalent to the namespace you pulled apart…) Commented Feb 4, 2013 at 22:52
  • 1
    you can also use vars(args) to get a dict Commented Feb 4, 2013 at 22:54

2 Answers 2

5

Update your local namespace with the result of the vars() function:

globals().update(vars(args))

This is generally not that great an idea; leave those attributes in the namespace instead.

You could create more problems than you solved with this approach, especially if you accidentally configure arguments with a dest name that shadows a built-in or local you care about, such as list or print or something. Have fun hunting down that bug!

Tim Peters already stated this in his Zen of Python:

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

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

9 Comments

+1. I forgot that vars(namespace) and namespace._get_kwargs() will return the same thing.
It's not merely a bad idea that makes for hard-to-read code--it's also a rich source of unintended bugs and security holes. You could easily overwrite globals and builtins--e.g. suppose you have a parameter named list? Or a parameter which can't be an identifier, like 2my-param?
@FrancisAvila: It's not necessarily a security hole, provided the parser has been set up with sane argument names. You cannot inject arbitrary argument destinations in any case. Besides, the user of this program already has local-user access to be able to run it..
tsk,tsk. You shouldn't modify locals. quoting from the documentation "The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter."
@mgilson: That mostly applies to functions; grab a parent function in the current call stack and try to update it's f_locals structure with new values for example and it'll fail.. But for modules (where locals() == globals() anyway, it'll work just fine. :-)
|
0

Probably the worst idea ever: since you can pass an arbitrary object to parse_args(), pass the __builtins__ module, so that all attributes can be looked up as local variables.

p = argparse.ArgumentParser()
p.add_argument("--foo")
p.parse_args( "--foo bar".split(), __builtins__)
print foo

This will even "work" for parameters whose destinations aren't valid Python identifiers:

# To use the example given by Francis Avila in his comment on Martijn Pieters' answer
getattr(__builtins__, '2my-param')

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.