Sean Mackesey
Sean Mackesey

Reputation: 10939

How can I create a separate namespace within a Python script?

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

Answers (5)

shx2
shx2

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

Bakuriu
Bakuriu

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

voodoogiant
voodoogiant

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

Robᵩ
Robᵩ

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

gabe
gabe

Reputation: 2511

It sounds like you want a python class. See the docs.

Depending on what you want exactly, you can define a bunch of variables as attributes of a class (either a variable of an instance or of the class itself) and access them that way.

Upvotes: 0

Related Questions