parse - metavar python
¿Cómo creo un espacio de nombres de Python(valor argparse.parse_args)? (3)
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
on the fly ( dict([("a",1),("b","c")])
) pero no puedo usarlo como Namespace
:
AttributeError: ''dict'' object has no attribute ''a''
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''
Puedes crear una clase simple:
class Namespace:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
y funcionará exactamente de la misma forma 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 delNamespace()
admiten pruebas de contención;''attrname'' in instance
es verdadero si la instancia del espacio de nombres tiene un atributo namendattrname
.SimpleNamespace
no lo hace. -
Namespace()
objetos delNamespace()
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 usandosorted(vars(instance).items())
. - Si bien
SimpleNamespace()
se implementa en C yNamespace()
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 lasSimpleNamespace()
deSimpleNamespace()
.
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'')