Kann ich ein Namespace-Objekt von veränderlichen zu unveränderlichen konvertieren?

Ich bekomme ein Namespace-Objekt aus Befehlszeilenargumenten. Und ich will es nicht ändern. Kann ich das machen oder hast du mal Ideen?

# -*- coding: utf-8 -*- import argparse def parse_args(): parser = argparse.ArgumentParser(description='This script is ...') parser.add_argument('--confdir', type=str, required=True) parser.add_argument('--outdir', type=str, required=True) return parser.parse_args() if __name__ == '__main__': mutable_namespace = parse_args() # I want to prevent overwrite like that. mutable_namespace.confdir = "xxx" 

2 Solutions collect form web for “Kann ich ein Namespace-Objekt von veränderlichen zu unveränderlichen konvertieren?”

Ich habe zunächst die benutzerdefinierte Namespace-Klasse vorgeschlagen, aber ich mag diese Idee, args zu einem NamedTuple besser zu kopieren.

Namedtuple

Eine weitere Möglichkeit besteht darin, die Werte von args zu einem unveränderlichen Objekt / Klasse zu kopieren. Ein benannter Tupel könnte den Job gut machen.

Erstellen Sie einen Namespace

 In [1157]: dest=['x','y'] In [1158]: args=argparse.Namespace() In [1159]: for name in dest: ......: setattr(args, name, 23) ......: In [1160]: args Out[1160]: Namespace(x=23, y=23) 

Definiere nun ein namedtuple

 In [1161]: from collections import namedtuple In [1163]: Foo = namedtuple('Foo',dest) 

Du könntest auch die Tupelnamen aus dem Namespace selbst (nach dem Parsing)

 Foo = namedtuple('Foo',vars(args).keys()) 

Erstellen Sie ein solches Tupel mit Werten aus args :

 In [1165]: foo=Foo(**vars(args)) In [1166]: foo Out[1166]: Foo(x=23, y=23) In [1167]: foo.x Out[1167]: 23 

Und es ist unveränderlich:

 In [1168]: foo.x=34 ... AttributeError: can't set attribute 

Ein solches namedtuple kann nicht als Namespace verwendet werden, da setattr(foo,'x',34) denselben Fehler erzeugt.

Ein sauberer Weg, um all dies zu tun ist, um alles in einer Funktion zu wickeln:

 def do_parse(): parser = .... Foo = namedtuple(...) args = parser.parse_args() foo = Foo(**vars(args)) return foo 

Der rufende Code sieht nie die veränderlichen args , nur die unveränderliche foo .

Benutzerdefinierte Namespace-Klasse

Um auf Ingaz Antwort argparse kann argparse deine eigene Namespace Klasse verwenden.

https://docs.python.org/3/library/argparse.html#the-namespace-object

 class MyNamespace(argparse.Namespace): pass <customize one or more methods> anamespace = MyNamespace() args = parser.parse_args(namespace=anamespace) 

Jetzt anamespace und anamespace verweisen auf das gleiche MyNamespace Objekt. Solange getattr(anamespace, adest) und setattr(anamespace, adest, avalue) arbeiten, kann argparse dieses Namespace-Objekt verwenden.

Nun können Sie setattr(anamespace, 'string', 'value') erlauben, aber nicht anamespace.string = value ? Ich denke, Sie können, aber es wird ein gutes Verständnis davon verlangen, wie der letztere Ausdruck funktioniert. Es kann nur ein Customizing erforderlich sein .__setattr__ , aber ich habe diesen Aspekt von Python nicht in einer Weile studiert.

Mit dem Design ist es möglich und sogar akzeptabel, 'monkey patch' der argparse namespace – mit einer benutzerdefinierten Klasse wie diese.

Sie können __setattr__ in Ihrem mutable_namespace neu definieren:

 class NotMutableException(Exception):pass class SomeObject(object): def init(self): self.x = 10 self.y = 20 some_obj = SomeObject() some_obj.z = 30 def not_setattr(self, name, value): raise NotMutableException type(some_obj).__setattr__ = not_setattr some_obj.a = 1000 
  • Einzelnes Unbekanntes über eine Sequenz in Python ausführen
  • Pip - Schwerwiegender Fehler beim Launcher: Der Prozess kann nicht mit '' '
  • Warum ist die Reihenfolge von mehreren `für` Liste Verständnis so wie es ist?
  • Python-Tastatur-Ereignisse ohne GUI (nicht blockierend)
  • Importieren von Modulen aus einem Geschwisterverzeichnis für py.test
  • Ist workerpool kompatibel mit python3.4 auf windows?
  • Ich muss über Textdatei iterieren und einen bestimmten Text ausdrucken, beginnend mit dem Ende der Erfüllung der Bedingung in Python 3
  • Löschen von Leerzeilen aus dem Jupyter Notebook
  • Pythonschleife durch String in verschachtelten Schlaufen
  • Wie kann ich einen Bereich in einer csv-Datei in Python sortieren?
  • Ändern Sie Schriftart u. Hintergrundfarbe im ipython Notizbuch
  • Python ist die beste Programmiersprache der Welt.