Reputation: 10939
I would like to store a bunch of variables under a Python namespace without creating a separate module. I notice that the result of ArgumentParser
's parse_args()
is a argparse.Namespace
object. You can access the arguments through dot-syntax.
from argparse import ArgumentParser
parser = ArgumentParser()
# some arg definitions here...
args = parser.parse_args() # returns a `argparse.Namespace` object
How can I create the equivalent of an argparse.Namespace
? I know I can do something similar with a dict
but I would like to use dot-syntax. Is there any built-in class that just lets you assign arbitrary attributes?
Upvotes: 4
Views: 5217
Reputation: 64298
A class can be used as a namespace, where the variables are class members:
class Namespace1:
foo = 'a'
bar = 5
To prevent callers from trying to instantiate, you can use a baseclass like:
class objectless(object):
def __new__(cls, *args, **kwargs):
raise RuntimeError('%s should not be instantiated' % cls)
And use it like:
class Namespace1(objectless):
...
Upvotes: 2
Reputation: 101919
Starting with python3.3 you can use types.SimpleNamespace
.
However an alternative is simply:
class Namespace(object):
pass
namespaceA = Namespace()
namespaceA.x = 1
The full code for SimpleNamespace
isn't much longer.
Note that you cannot simply use an object
instance:
>>> o = object()
>>> o.x = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'x'
This is because instances of object
do not have a __dict__
attribute:
>>> vars(object())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: vars() argument must have __dict__ attribute
Which means you cannot set the attributes of an instance of object
.
Any object
subclass that does not have the __slots__
attribute set does have the __dict__
which is used (by default) to store/retrieve attributes:
>>> class Namespace(object):
... pass
...
>>> a = Namespace()
>>> a.x = 1 # same as as.__dict__['a'] = 1
>>> a.__dict__
{'x': 1}
For further information about attribute setting/lookup you should learn about descriptors.
Upvotes: 11
Reputation: 2148
If I'm understanding correctly, you want to dynamically add attributes to it. For example, a class parses command-line flags you access them directly like args.verbose, right? If so, you may be thinking of setattr() that lets you add arbitrary attributes.
class Foo(object):
pass
foo = Foo()
setattr(foo, 'ack', 'bar')
print(foo.ack) # prints 'bar'
Upvotes: 0
Reputation: 168616
If you want "the equivalent of an argparse.Namespace
", use argparse.Namespace
:
from argparse import Namespace
ns = Namespace(a=1)
print ns.a
Upvotes: 1