Pour tester interactivement mon script python, je voudrais créer un objet Namespace
, similaire à ce qui serait retourné par argparse.parse_args()
. La manière évidente,
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.parse_args()
Namespace()
>>> parser.parse_args("-a")
usage: [-h]
: error: unrecognized arguments: - a
Process Python exited abnormally with code 2
peut entraîner Python repl sortie (comme ci-dessus) sur une erreur idiote.
Donc, quel est le moyen le plus simple de créer un Python avec un ensemble d'attributs donné?
Par exemple, je peux créer un dict
à la volée (dict([("a",1),("b","c")])
) mais je ne peux pas l'utiliser comme Namespace
:
AttributeError: 'dict' object has no attribute 'a'
Vous pouvez créer une classe simple:
class Namespace:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
et cela fonctionnera exactement de la même manière que la classe argparse
Namespace
en ce qui concerne les attributs:
>>> args = Namespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'
Alternativement, il suffit d'importer la classe ; il est disponible depuis le module argparse
:
from argparse import Namespace
args = Namespace(a=1, b='c')
Depuis Python 3.3, il y a aussi types.SimpleNamespace
, qui fait essentiellement la même chose:
>>> from types import SimpleNamespace
>>> args = SimpleNamespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'
Les deux types sont distincts; SimpleNamespace
est principalement utilisé pour l'attribut sys.implementation
et la valeur de retour de time.get_clock_info()
.
Comparaisons supplémentaires:
instance_a == instance_b
est vrai si elles ont les mêmes attributs avec les mêmes valeurs.__repr__
Utile pour montrer leurs attributs.Namespace()
les objets prennent en charge les tests de confinement; 'attrname' in instance
Est vrai si l'instance d'espace de noms a un attribut namend attrname
. SimpleNamespace
ne fonctionne pas.Namespace()
ont une méthode ._get_kwargs()
non documentée qui retourne une liste triée d'attributs (name, value)
pour cette instance. Vous pouvez obtenir la même chose pour chaque classe en utilisant sorted(vars(instance).items())
.SimpleNamespace()
est implémenté en C et Namespace()
est implémenté en Python, l'accès aux attributs n'est pas plus rapide car les deux utilisent le même stockage __dict__
Pour les attributs. Les tests d'égalité et la production de la représentation sont un peu plus rapides pour les instances SimpleNamespace()
.Il est désormais recommandé d'utiliser SimpleNamespace à partir du module types. Il fait la même chose que la réponse acceptée, sauf qu'il sera plus rapide et comportera quelques éléments supplémentaires tels que equals et repr.
from types import SimpleNamespace
sn = SimpleNamespace()
sn.a = 'test'
sn.a
# output
'test'