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.

share|improve this question
You could loop over __dict__ or use inspect... – sr2222 8 hours ago
Or just locals().update(namespace._get_kwargs()). – abarnert 8 hours ago
1  
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…) – abarnert 8 hours ago
you can also use vars(args) to get a dict – Francesco Montesano 8 hours ago
feedback

2 Answers

up vote 3 down vote accepted

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

locals().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!

share|improve this answer
+1. I forgot that vars(namespace) and namespace._get_kwargs() will return the same thing. – abarnert 8 hours ago
1  
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? – Francis Avila 8 hours ago
2  
@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.. – Martijn Pieters 8 hours ago
feedback

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')
share|improve this answer
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.