user7088941
user7088941

Reputation: 361

What is Python's "Namespace" object?

I know what namespaces are. But when running

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar')
parser.parse_args(['XXX']) # outputs:  Namespace(bar='XXX')

What kind of object is Namespace(bar='XXX')? I find this totally confusing.

Reading the argparse docs, it says "Most ArgumentParser actions add some value as an attribute of the object returned by parse_args()". Shouldn't this object then appear when running globals()? Or how can I introspect it?

Upvotes: 15

Views: 16120

Answers (3)

chepner
chepner

Reputation: 530960

Namespace is basically just a bare-bones class, on whose instances you can define attributes, with a few niceties:

  • A nice __repr__
  • Only keyword arguments can be used to instantiate it, preventing "anonymous" attributes.
  • A convenient method to check if an attribute exists (foo in Namespace(bar=3) evaluates to False)
  • Equality with other Namespace instances based on having identical attributes and attribute values. (E.g. ,Namespace(foo=3, bar=5) == Namespace(bar=5, foo=3))

Instances of Namespace are returned by parse_args:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar')
args = parser.parse_args(['XXX'])

assert args.bar == 'XXX'

Upvotes: 4

Silvio Mayolo
Silvio Mayolo

Reputation: 70267

Samwise's answer is very good, but let me answer the other part of the question.

Or how can I introspect it?

Being able to introspect objects is a valuable skill in any language, so let's approach this as though Namespace is a completely unknown type.

>>> obj = parser.parse_args(['XXX']) # outputs:  Namespace(bar='XXX')

Your first instinct is good. See if there's a Namespace in the global scope, which there isn't.

>>> Namespace
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Namespace' is not defined

So let's see the actual type of the thing. The Namespace(bar='XXX') printer syntax is coming from a __str__ or __repr__ method somewhere, so let's see what the type actually is.

>>> type(obj)
<class 'argparse.Namespace'>

and its module

>>> type(obj).__module__
'argparse'

Now it's a pretty safe bet that we can do from argparse import Namespace and get the type. Beyond that, we can do

>>> help(argparse.Namespace)

in the interactive interpreter to get detailed documentation on the Namespace class, all with no Internet connection necessary.

Upvotes: 15

Samwise
Samwise

Reputation: 71434

It's simply a container for the data that parse_args generates.

https://docs.python.org/3/library/argparse.html#argparse.Namespace

This class is deliberately simple, just an object subclass with a readable string representation.

Just do parser.parse_args(...).bar to get the value of your bar argument. That's all there is to that object. Per the doc, you can also convert it to a dict via vars().

The symbol Namespace doesn't appear when running globals() because you didn't import it individually. (You can access it as argparse.Namespace if you want to.) It's not necessary to touch it at all, though, because you don't need to instantiate a Namespace yourself. I've used argparse many times and until seeing this question never paid attention to the name of the object type that it returns -- it's totally unimportant to the practical applications of argparse.

Upvotes: 6

Related Questions