Python ArgumentParser dynamische Parametervergabe

jb_alvarado

Lieutenant
Registriert
Sep. 2015
Beiträge
557
Hallo Leute,
ich würde gerne die Argumente für den ArgumentParser dynamisch vergeben. Also nehmen wir an ich habe diese YAML Config:

JSON:
short: -v
long: --volume
action:
help: set audio volume

Dabei können jeweils short, oder long einen Wert besitzen oder nicht. Diese Werte möchte ich nun zu einem Argument hinzufügen. Also in etwa so:

Python:
stdin_parser.add_argument(
    ', '.join(filter(None, [config.get('short'), config.get('long')])),
    help=config.get('help')
)

Das geht so halt nicht, weil .join mir einen String aus beiden Werten erzeugt, aber ich denke es verdeutlicht das Prinzip.

Habt ihr eine Idee wie ich das lösen kann?
 
Du kannst doch die YAML Config sicherlich einlesen und hast dann ein Dictionary oder?

In dem Fall einfach Parameter Expansion nutzen also:

Python:
my_config = magic_yaml_parser.load("my_config.yaml")
stdin_parser.add_argument(my_config**)
 
Das klingt gut, geht so aber nicht. Hast du da vielleicht ein komplettes Beispiel?

Habe es so probier:

Python:
from argparse import ArgumentParser

stdin_parser = ArgumentParser(description='dynamic args')

config = {
    'short': None,
    'long': '--volume',
    'action': None,
    'help': 'set audio volume'
}

stdin_parser.add_argument(**config)

stdin_args = stdin_parser.parse_args()


if __name__ == '__main__':
    print(stdin_parser.print_help())

Die Parameternamen kann ich natürlich ändern, wenn nötig.
 
@DaysShadow das müsste dann stdin_parser.add_argument(**my_config) sein. aber auch dann klappt es nicht, weil add_argument(short='-v', long='--volume', action=None, help='set audio volume') aufgerufen wird und die funktion die parameter "short" und "long" nicht kennt.

@jb_alvarado das funktioniert nicht, weil dein komma-separierter string zwar so aussieht, was du im code als parameter schreiben würdest, aber für die funktion es nur ein parameter ist. du musst einfach nur die expandierte liste der namen übergeben + den "help" parameter.

Python:
import argparse

config = {
    'short': '-v',
    'long': '--volume',
    'action': None,
    'help': 'set audio volume'
}

if __name__ == '__main__':

    parser = argparse.ArgumentParser()

    parser.add_argument(
        *filter(None, [config.get('short'), config.get('long')]),
        help=config['help']
    )
  
    parsed = parser.parse_args()

Code:
$ python bla.py --help
usage: bla.py [-h] [-v VOLUME]

optional arguments:
  -h, --help            show this help message and exit
  -v VOLUME, --volume VOLUME
                        set audio volume
 
  • Gefällt mir
Reaktionen: jb_alvarado und DaysShadow
Danke @0x8100, das klappt super so! Aber @DaysShadow Tipp war auch praktisch, weil ich so meine YAML Datei noch etwas dynamisch gestalten kann. Nämlich in dem ich short und long daraus extrahieren, und den Rest als Key/Value Paare and den argparser ran hängen kann.

Muss mich mal mit dem dem Expandieren von Listen und Dicts beschäftigen, stolpere immer wieder drüber, aber selbst verwende ich sie noch gar nicht. Dabei ist das echt praktisch!
 
  • Gefällt mir
Reaktionen: DaysShadow
wenn du dein yaml so aufbaust, wie add_argument() die parameter erwartet, kannst du das natürlich machen :)
 
  • Gefällt mir
Reaktionen: jb_alvarado
Zurück
Oben