380 Stimmen

Was ist der richtige Weg, um Python argparse.Namespace() als ein Dictionary zu behandeln?

Wenn ich die Ergebnisse von argparse.ArgumentParser() verwenden möchte, die ein Namespace-Objekt sind, mit einer Methode, die ein Wörterbuch oder einem ähnlichen Objekt erwartet (siehe collections.Mapping), wie mache ich das richtig?

C:\>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> args.baz = 'yippee'
>>> args['baz']
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'Namespace' object has no attribute '__getitem__'
>>> dir(args)
['__class__', '__contains__', '__delattr__', '__dict__', '__doc__', '__eq__', '_
_format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__
', '__str__', '__subclasshook__', '__weakref__', '_get_args', '_get_kwargs', 'ba
r', 'baz', 'foo']

Ist es richtig, in ein Objekt "hineinzugreifen" und dessen __dict__-Eigenschaft zu verwenden?

Ich denke die Antwort ist nein: __dict__ wirkt wie eine Konvention für die Implementierung, aber nicht für eine Schnittstelle, so wie __getattribute__ oder __setattr__ oder __contains__ zu sein scheinen.

594voto

Raymond Hettinger Punkte 197261

Sie können das Wörterbuch des Namespaces mit vars() abrufen:

>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> d = vars(args)
>>> d
{'foo': 1, 'bar': [1, 2, 3]}

Sie können das Wörterbuch direkt ändern, wenn Sie möchten:

>>> d['baz'] = 'store me'
>>> args.baz
'store me'

Ja, es ist in Ordnung, auf das __dict__-Attribut zuzugreifen. Es handelt sich um ein wohldefiniertes, getestetes und garantiertes Verhalten.

121voto

Eugene Yarmash Punkte 130008

Direkt aus dem Pferdemaul:

Wenn Sie eine wörterbuchähnliche Ansicht der Attribute bevorzugen, können Sie das Standard-Python-Idiom vars() verwenden:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

— Die Python Standardbibliothek, 16.4.4.6. Das Namensraumobjekt

2voto

Brad Parks Punkte 59613

Beachten Sie, dass, wenn Sie versuchen, args als dict zu behandeln, um herauszufinden, ob es ein Attribut hat, können Sie stattdessen einfach Folgendes tun:

if hasattr(args, 'someProperty'):
    a.someProperty

mehr Informationen auf hasattr und ähnliche Antwort auf eine andere Frage

Sie können auch den Wert abrufen, wenn Sie die ähnliche getattr Methode bevorzugen:

value = getattr(args, 'someProperty')

0voto

msw Punkte 41469

Ist es korrekt, "in ein Objekt hineinzugreifen" und seine dict-Eigenschaft zu verwenden?

Im Allgemeinen würde ich sagen "nein". Allerdings erscheint mir Namespace als überkonstruiert, möglicherweise aus der Zeit, als Klassen nicht von integrierten Typen erben konnten.

Andererseits präsentiert Namespace jedoch einen aufgabenorientierten Ansatz für argparse, und mir fällt keine Situation ein, in der es erforderlich wäre, das __dict__ abzurufen, doch die Grenzen meiner Vorstellungskraft sind nicht dieselben wie Ihre.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X