Argparse: Abhängige Argumente?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

habe ein etwas schwieriges Problem mit argparse.

Ich habe zwei Argumente, A und B.
A ist ein Schalter der entweder True oder False ist.
B sei eine Liste von Integern.

Nun möchte ich, dass Argparse eine Exception wirft, wenn B nicht nur aus Geraden bzw. Ungeraden Zahlen besteht (abhängig von dem Wert von A: True -> nur Gerade, False nur Ungerade).

Nur habe ich keien Ahung wie ich das am besten mache.

Wer sich wundert warum man sowas machen möchte, in meinem richtigen Programm ist das ganze etwas komplizierter.
Ich muss, um die Eingabe zu überprüfen ein externes Tool ansprechen und dessen Konfiguration muss ich aber auch irgendwie einlesen.
Ergo habe ich Parameter für das Tool und kann danach direkt im Argparser checken, dass die Eingabe korrekt ist oder nicht.
Vlt könnte man zwei Parser verwenden (mit partial parsing) aber bin mir nicht sicher, ob man mehrere Argparser hinter einander laufen lassen kann.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo,

ich werfe einfach mal einen anderen Lösungsansatz in den Raum. Statt B von A abhängig zu machen, würde ich für die Zustände von A einfach zwei Optionen -p für A=True und -q für A=False einführen. Dann kannst du dein Program mittels

Code: Alles auswählen

spam -p 1 2 3 4

Code: Alles auswählen

spam -q 1 2 3 4 5
aufrufen. Für p und q müsstest du dann nur noch Mutual exclusion verwenden.

Ich weiß aber ehrlich gesagt nicht, welches Interface nun schöner ist.
Das Leben ist wie ein Tennisball.
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

erstmal Danke für die Antwort.
Leider Hilft sie mir nicht wirklich.

Dein Vorschlag würde gehen, wenn es sich wirklich um so einen einfachen Fall wie in meinem Beispiel handeln würde.
Vlt. sollte ich es noch etwas mehr Erklären.
Ich greife aus meinem Python Skript auf ein externes Tool zu.
Um dieses zu finden und zu konfigurieren brauche ich Parameter (A).
Danach wird dieses Tool verwendet, um die Liste B zu prüfen.

Ich befürchte, das ganze ist nicht einfach so zu lösen.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@p90
Ich würde dafür entweder eine custom action schreiben oder die Abhängigkeit schlichtweg außerhalb prüfen:

Code: Alles auswählen

import argparse
import sys

def check_dependence(kwargs):
    print 'Tool: {kwargs.tool}\nValues: {kwargs.values}\n'.format(kwargs=kwargs)
    if kwargs.tool:
        if not kwargs.values:
            print 'No values!\n'
        else:
            # do some stuff with kwargs.values
            print 'OK\n'
    else:
        if kwargs.values:
            print 'No tool!\n'

def main(args):
    p = argparse.ArgumentParser('My Tool')
    p.add_argument('--tool', nargs='+')
    p.add_argument('--values', nargs='+')
    check_dependence(p.parse_args(args))


if __name__ == '__main__':
    main(sys.argv[1:])

Code: Alles auswählen

$ python ./depend_arg.py --tool /path/to/tool
Tool: ['/path/to/tool']
Values: None

No values!

$ python ./depend_arg.py --values one two three
Tool: None
Values: ['one', 'two', 'three']

No tool!

$ python ./depend_arg.py --tool /path/to/tool --values one two three
Tool: ['/path/to/tool']
Values: ['one', 'two', 'three']

OK
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6732
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@p90: Wie du ja bereits bemerkt hast, solltest du nicht Anwendungsfälle erfinden, sondern das tatsächliche Problem schildern. Was ich nicht verstehe: Warum siehst du es als so kompliziert an, deinem Tool Parameter zu übergeben? Wenn das Tool vernünftig programmiert wurde, dann sollte es bei unpassenden Eingabewerten einen Exitcode ungleich Null ausspucken. Wenn du jetzt dein externes Tool (z.B. mittels `subprocess.check_call()`) aufrufst und den Exitcode (bzw bei der genannten Funktion die Exception) prüfst (abfängst), dann kannst du in deinem Programm ggf ausgeben, dass bei der Parameterübergabe etwas nicht funktioniert hat. Oder sehe ich das falsch?
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

@snafu

Natürlich sollte ich einen Anwendungsfall erfinden. Nämlich den das das Problem mit dem wenigsten Text/Code beschreibt sodass man dann das präsentierte Problem lösen kann und sich nicht erst durch 1000 Zeilen anderen Code suchen muss die mit der Frage gar nichts zu tun haben. Minimalbeispiel halt.

Zu deiner Frage:
Es ging hier nicht darum wie man ein Tool aufruft sondern wie ich mit Argparser die Korrektheit von Eingaben prüfe wenn diese voneinander abhängen. Ob dies möglich ist oder nicht ist absolut unabhängig von dem Problem, das ich gerade Lösen will.
Ich vermute mittlerweile, dass sich dies nicht direkt aus Argparse heraus lösen lässt sondern wie mutetella schriebt durch eine äußere Prüfung durchgeführt werden muss. Das verkompliziert mein Programm und nimmt Argparse leider einige Funktionen für mich weg aber gut. Geht nicht anders.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

p90 hat geschrieben:Das verkompliziert mein Programm und nimmt Argparse leider einige Funktionen für mich weg aber gut.
`argparse` ist ein Parser. Das Überprüfen der Argumente gehört da nicht rein. Wenn sich Dein Programm dadurch verkompliziert, hast Du vielleicht schon zu vieles miteinander verwoben, was nicht zusammengehört. Die Versuchung, beim Parsen auch gleich zu Validieren ist groß, da man die Werte ja quasi schon "in der Hand hält". Aber letztlich ist die weitere Verarbeitung der Werte tatsächlich einfacher und auch nachvollziehbarer, wenn man vom Parser die rohen Werte bekommt und an anderer Stelle überprüft.
Und wenn es Gründe für eine Verbindung zwischen Parser und Weiterverarbeitung gibt, dann ist das ja über die custom action möglich.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten