To interactively test my python script, I would like to create a Namespace object, similar to what would be returned by argparse.parse_args().
The obvious way,
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.parse_args()
Namespace()
>>> parser.parse_args("-a")
usage: [-h]
: error: unrecognized arguments: - a
Process Python exited abnormally with code 2
may result in Python repl exiting (as above) on a silly error.
So, what is the easiest way to create a Python namespace with a given set of attributes?
E.g., I can create a dict on the fly (dict([("a",1),("b","c")])) but I cannot use it as a Namespace:
AttributeError: 'dict' object has no attribute 'a'
You can create a simple class:
class Namespace:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
and it'll work the exact same way as the argparse Namespace class when it comes to attributes:
>>> args = Namespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'
Alternatively, just import the class; it is available from the argparse module:
from argparse import Namespace
args = Namespace(a=1, b='c')
As of Python 3.3, there is also types.SimpleNamespace, which essentially does the same thing:
>>> from types import SimpleNamespace
>>> args = SimpleNamespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'
The two types are distinct; SimpleNamespace is primarily used for the sys.implementation attribute and the return value of time.get_clock_info().
Further comparisons:
- Both classes support equality testing; for two instances of the same class,
instance_a == instance_bis true if they have the same attributes with the same values. - Both classes have a helpful
__repr__to show what attributes they have. Namespace()objects support containment testing;'attrname' in instanceis true if the namespace instance has an attribute namendattrname.SimpleNamespacedoes not.Namespace()objects have an undocumented._get_kwargs()method that returns a sorted list of(name, value)attributes for that instance. You can get the same for either class usingsorted(vars(instance).items()).- While
SimpleNamespace()is implemented in C andNamespace()is implemented in Python, attribute access is no faster because both use the same__dict__storage for the attributes. Equality testing and producing the representation are a little faster forSimpleNamespace()instances.
It is now recommended to use SimpleNamespace from the types module. It does the same thing as the accepted answer except for it will be faster and have a few more builtins such as equals and repr.
from types import SimpleNamespace
sn = SimpleNamespace()
sn.a = 'test'
sn.a
# output
'test'
argparse documentation show various examples of what you're trying to do:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a")
parser.parse_args(['-a 12'])
>>> Namespace(a=' 12')
来源:https://stackoverflow.com/questions/28345780/how-do-i-create-a-python-namespace-argparse-parse-args-value