Ich verwende argparse Aktion, um verschiedene Daten zu einer Klasse hinzuzufügen. Ich möchte diese Aktion für den Standardwert verwenden, wenn dieses Argument nicht in der Befehlszeile angegeben wird. Ist das möglich? Danke!Ursache Pythons Argaparse zum Ausführen der Aktion für den Standard
Antwort
argparse
verwendet nicht die action
beim Anwenden der default
. Es verwendet nur setattr
. Es kann die type
verwenden, wenn der Standardwert eine Zeichenfolge ist. Aber Sie können die action
direkt aufrufen.
Hier verwende ich eine benutzerdefinierte Aktionsklasse aus der Dokumentation ausgeliehen. In der ersten parse_args
passiert nichts. Dann erstelle ich eine neue namespace
, und rufen Sie die Aktion auf den Standard. Dann übergebe ich diesen Namensraum an parse_args
. Um das zu verstehen, müssen Sie es in eine interaktive Shell importieren und die Attribute des Namespace und der Aktion untersuchen.
# sample custom action from docs
class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
print('Setting: %r %r %r' % (namespace, values, option_string))
setattr(namespace, self.dest, 'action:'+values)
p = argparse.ArgumentParser()
a1 = p.add_argument('--foo', action=FooAction, default='default')
print 'action:',a1
print p.parse_args([])
ns = argparse.Namespace()
a1(p, ns, a1.default, 'no string') # call action
print p.parse_args([],ns)
print p.parse_args(['--foo','1'],ns)
die produziert:
action: FooAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default='default', type=None, choices=None, help=None, metavar=None)
Namespace(foo='default')
Setting: Namespace() 'default' 'no string'
Namespace(foo='action:default')
Setting: Namespace(foo='action:default') '1' '--foo'
Namespace(foo='action:1')
I den Ausgang zugeschnitten zu markieren, wenn die Aktion verwendet wird.
Hier ist eine Möglichkeit, eine besondere Aktion auf dem Argument durchführen, die nicht auf der Kommandozeile angegeben wird (oder mit einem Wert angegeben == auf die Standardeinstellung). Es ist eine Vereinfachung der in https://stackoverflow.com/a/24638908/901925 angegebenen Klasse.
class Parser1:
def __init__(self, desc):
self.parser = argparse.ArgumentParser(description=desc)
self.actions = []
def milestone(self, help_='milestone for latest release.', default=None):
action = self.parser.add_argument('-m', '--milestone', help=help_, default=default)
self.actions.append(action)
return self
def parse(self):
args = self.parser.parse_args()
for a in self.actions:
if getattr(args, a.dest) == a.default:
print 'Please specify', a.dest
values = raw_input('>')
setattr(args, a.dest, values)
return args
print Parser1('desc').milestone(default='PROMPT').parse()
Die Abfrage erfolgt nach parse_args
. Ich sehe keinen Grund wieder parse_args
anzurufen.
Danke. Dies ist sicherlich eine Möglichkeit, dies zu tun. (Außerdem bietet es gute Beispiele für andere Teile der Verwendung von Argarse). Ich habe den Körper von FooAction .__ call__ zu einer anderen Methode gezogen und manuell über Argumente wie deine a1 iteriert. Es ist wirklich eine Schande, dass es nicht eingebaut ist. –
+1 - Ich habe es verwendet, um den Benutzer zu fragen, wenn keine Option übergeben wird - muss es wirklich so hacky sein? Keine Möglichkeit über die API eine Aktion auszuführen, wenn eine Option nicht gesetzt ist? –
Ich würde warten, bis die gesamte Befehlszeile geparst ist, bevor ich den Benutzer nach weiteren Eingaben frage. Der einfachste Weg, dies zu tun, ist 'args = parse_args ...', und dann meine Aktion auf den Inhalt von 'args. Kein Versuch, etwas zu tun "das erste Mal, dass ich keine Option finde"! – hpaulj
Ich brauchte den Benutzer aufzufordern, wenn keine Option angegeben wurde - das ist, wie ich es tat:
class _PromptUserAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values == self.default:
print 'Please specify', self.dest
values = raw_input('>')
setattr(namespace, self.dest, values)
class Parser:
def __init__(self, desc, add_h=True):
self.parser = argparse.ArgumentParser(description=desc, add_help=add_h,
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
#actions to be run on options if not specified (using default to check)
self.actions = []
@staticmethod
def new(description, add_help=True):
return Parser(description, add_help)
# ...
def milestone(self, help_='Specify the milestone for latest release.'):
action = self.parser.add_argument('-m', '--milestone',
dest='milestone',
action=_PromptUserAction,
default='PROMPT', # needed I think
type=str,
help=help_)
self.actions.append(action)
return self
def parse(self):
"""
Return an object which can be used to get the arguments as in:
parser_instance.parse().milestone
:return: ArgumentParser
"""
args = self.parser.parse_args()
# see: http://stackoverflow.com/a/21588198/281545
dic = vars(args)
ns = argparse.Namespace()
for a in self.actions:
if dic[a.dest] == a.default:
a(self.parser, ns, a.default) # call action
# duh - can I avoid it ?
import sys
return self.parser.parse_args(sys.argv[1:],ns)
Ich bin interessiert, wenn dies irgendwie ohne getan werden kann, um die args (der import sys
Teil) zu Analysepunkten . Vielleicht einige Konstruktoroptionen für argparse.Action
?
Ich habe eine vereinfachte Version deines Beispiels zu meiner Antwort hinzugefügt. Ist das die Funktionalität, die Sie suchen? – hpaulj
@hpaulj: wie Pythonic - danke - ich bestand darauf zu versuchen, "meine Aktion zu laufen" - wird es irgendwann verwenden und posten zurück, wenn ich über irgendwelche Seltsamkeit stoße –
- 1. Standard Aktion
- 2. Magento Standard Controller Aktion
- 3. Standard-Medienformatierer für eine WebAPI-Aktion festlegen
- 4. Delphi Standard-Datenmenge Aktion Tdatasetdelete
- 5. Ausführen der Aktion nach der Fragmenttransaktionsanimation
- 6. Aktion für Zeilenbereich in sed/awk ausführen
- 7. die Standard-String-Wert von Pythons collections.defaultdict
- 8. Was entspricht Pythons Java-Standard for-loop?
- 9. executorService.scheduleAtFixedRate zum Ausführen der Aufgabe für immer
- 10. Ausführen von JSON über Pythons eval()?
- 11. Programmatische Ermittlung der Ursache für IOException?
- 12. Code vor der Aktion des Controllers ausführen
- 13. BeautifulSoup zum Ausführen für Python
- 14. Aktion ohne Weiterleitung ausführen
- 15. Aktion zum Delegieren: neue Aktion oder Casting-Aktion?
- 16. Möglichkeit zum Festlegen der Standard-Genauigkeit für alle Streams
- 17. Warum enthält der Standard-Object.toString() den Hashcode?
- 18. asp.net mvc Ausführen OrderProduct Aktion von der Übersichtsansicht
- 19. Android EditText setText Ursache Softkeyboard zum Einfrieren
- 20. Get Ausführen Aktion in HttpModule
- 21. Eine Aktion ausführen, wenn die Eingabe den Anforderungen entspricht
- 22. Gibt es einen Standard für den Kontextaustausch?
- 23. Ausführen einer Aktion, wenn die Seite
- 24. AngularJS Aktion ausführen nach $ scope.emit
- 25. Ein Ersatz für Pythons httplib?
- 26. Wo zum Ausführen der Kopie Befehl für Amazon Redshift
- 27. Verwenden von PackageMaker zum Ausführen eines Skripts bei der Installation
- 28. Aktion <T> vs Standard Zurück
- 29. Eine Anweisung zum Anpassen von Pythons Makrosyntax
- 30. Grundlegende Ursache für java.io.FileNotFoundException ermitteln
möglich Duplikat von [Python argparse: Standardwert oder angegebener Wert] (http://stackoverflow.com/questions/15301147/python-argparse-default-value-or-specified-value) –
@LutzHorn, das ist nicht Ganz was ich brauche (glaube ich nicht), weil ich 1: argname = val und 2: eine beliebige argparse.Action speichern möchte, als ob --argname = val an der Kommandozeile gesetzt wurde –