¿Cómo creo un espacio de nombres de Python (valor de argparse.parse_args)?

Para probar de forma interactiva mi script de Python, me gustaría crear un objeto de Namespace , similar a lo que sería devuelto por argparse.parse_args() . La forma obvia,

 >>> 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 

puede dar como resultado que Python repl salga (como anteriormente) en un error tonto.

Entonces, ¿cuál es la forma más fácil de crear un espacio de nombres Python con un conjunto dado de atributos?

Por ejemplo, puedo crear un dict sobre la marcha ( dict([("a",1),("b","c")]) ) pero no puedo usarlo como Namespace :

 AttributeError: 'dict' object has no attribute 'a' 

Puedes crear una clase simple:

 class Namespace: def __init__(self, **kwargs): self.__dict__.update(kwargs) 

y funcionará exactamente de la misma manera que la clase de Namespace argparse cuando se trata de atributos:

 >>> args = Namespace(a=1, b='c') >>> args.a 1 >>> args.b 'c' 

Alternativamente, solo importa la clase ; está disponible desde el módulo argparse :

 from argparse import Namespace args = Namespace(a=1, b='c') 

A partir de Python 3.3, también hay types.SimpleNamespace , que esencialmente hace lo mismo:

 >>> from types import SimpleNamespace >>> args = SimpleNamespace(a=1, b='c') >>> args.a 1 >>> args.b 'c' 

Los dos tipos son distintos; SimpleNamespace se usa principalmente para el atributo sys.implementation y el valor de retorno de time.get_clock_info() .

Otras comparaciones:

  • Ambas clases apoyan las pruebas de igualdad; para dos instancias de la misma clase, instance_a == instance_b es verdadera si tienen los mismos atributos con los mismos valores.
  • Ambas clases tienen una __repr__ útil para mostrar qué atributos tienen.
  • Namespace() objetos del Namespace() admiten pruebas de contención; 'attrname' in instance es verdadero si la instancia del espacio de nombres tiene un atributo namend attrname . SimpleNamespace no lo hace.
  • Namespace() objetos del Namespace() tienen un ._get_kwargs() no documentado ._get_kwargs() que devuelve una lista ordenada de atributos (name, value) para esa instancia. Puede obtener lo mismo para cualquiera de las clases usando sorted(vars(instance).items()) .
  • Si bien SimpleNamespace() se implementa en C y Namespace() se implementa en Python, el acceso a los atributos no es más rápido porque ambos usan el mismo almacenamiento __dict__ para los atributos. Las pruebas de igualdad y la producción de la representación son un poco más rápidas para las SimpleNamespace() de SimpleNamespace() .

Ahora se recomienda usar SimpleNamespace desde el módulo de tipos. Hace lo mismo que la respuesta aceptada, excepto que será más rápida y tendrá algunas más incorporaciones, como iguales y repr.

 from types import SimpleNamespace sn = SimpleNamespace() sn.a = 'test' sn.a # output 'test' 

La documentación argparse muestra varios ejemplos de lo que estás tratando de hacer:

 import argparse parser = argparse.ArgumentParser() parser.add_argument("-a") parser.parse_args(['-a 12']) >>> Namespace(a=' 12')