argparse ist ein nützliches Paket zum Erstellen von Befehlszeilenskripten mit optionalen Argumenten in Python. Es ist ein praktisches Paket, aber ich habe Dutzende Male gemacht, um Argumente mit Funktionen fest zu machen und sie erneut mit Argparse zu schreiben, und ich war von dem Gedanken getrieben, dass diese Arbeit nutzlos war. Also lass es uns automatisieren.
In dem Kommentar wurde mir gesagt, dass ich das Gleiche wie Klick mache, und ich dachte, ich hätte das Rad für eine Weile neu erfunden, aber als ich versuchte, Klick zu verwenden, scheint es anders zu sein, also werde ich es hinzufügen .. Die Funktion von click besteht darin, dass die Definition von Optionen und Argumenten, die von argparse geschrieben wurden, an jede Funktion als Dekorateur verteilt werden kann und die Argumente der Funktion nicht automatisch als Optionen registriert werden. Schließlich schreiben Sie anstelle von add_argument einfach @ click.option, und der Inhalt, den Sie schreiben, ändert sich nicht so sehr. Das bedeutet nicht, dass das Klicken schlecht ist, es ist ein anderer Zweck. Click ist ein großartiges Paket zum Organisieren und Schreiben sowie zur Verbesserung der Lesbarkeit. Diesmal habe ich es jedoch grob geschrieben, um "alle Argumente der erstellten Funktion automatisch als Befehlszeilenargumente zu registrieren!". Daher kann die folgende Überlegung für ein einfaches, aber variables Skript dennoch nützlich sein. Unbekannt··. Im Gegenteil, ich habe versucht, mit Klick zu arbeiten, und viele Funktionen gefunden, die in anderen Szenen nützlich sein könnten. Deshalb werde ich den Inhalt beim nächsten Mal separat zusammenfassen.
Ein Paket namens inspect wird für die Analyse von Funktionsargumenten verwendet. Da ich python2.7 verwende, verwende ich die alte getargspec, aber für python3 verwenden Sie getfullargspec.
from inspect import getargspec
def func(aaa=1, bbb="a", ccc=[1,2,3,]):
pass
args, varargs, keywords, defaults = getargspec(func)
print 'args: ', args
print 'varargs', varargs
print 'keywords: ', keywords
print 'defaults: ', defaults
Wenn ich das oben genannte ausführe, erhalte ich die folgende Ausgabe:
args: ['aaa', 'bbb', 'ccc']
varargs None
keywords: None
defaults: (1, 'a', [1, 2, 3])
Verwenden Sie diese Informationen, um Argparse-Optionen automatisch zu registrieren.
from inspect import getargspec
def func(aaa=1, bbb="a", ccc=[1,2,3,]):
pass
args, varargs, keywords, defaults = getargspec(func)
import argparse
parser = argparse.ArgumentParser()
for arg, default in zip(args, defaults):
parser.add_argument(
'--' + arg,
default=default,
type=type(default)
)
print parser.parse_args()
Wenn Sie die obigen Schritte ausführen, erhalten Sie das folgende Namespace-Objekt:
Namespace(aaa=1, bbb='a', ccc=[1, 2, 3])
Tatsächlich reicht im obigen Fall die Entsprechung zu Argumenten variabler Länge nicht aus. Unten finden Sie den Code, der Argumente für Argumente variabler Länge hinzufügt, obwohl er etwas länger sein wird.
from inspect import getargspec
def func(aaa=1, bbb="a", ccc=[1,2,3,]):
pass
args, varargs, keywords, defaults = getargspec(func)
import argparse
parser = argparse.ArgumentParser()
for arg, default in zip(args, defaults):
if type(default) is tuple or type(default) is list:
parser.add_argument(
'--' + arg,
default=default,
type=type(default),
nargs='+'
)
else:
parser.add_argument(
'--' + arg,
default=default,
type=type(default)
)
Wenn das Argument eine Liste oder ein Tapple ist, fügen Sie das Argument nargs zu add_argument hinzu.
Im Fall eines Bool-Wert-Arguments wird der Wert eindeutig bestimmt, wenn er nicht der Standardwert ist. Daher wird häufig das Akronym disable angegeben, enable anstelle von True, False, um eine Option festzulegen, die keinen Wert annimmt. .. Einschließlich dieser Entsprechung wird es wie folgt.
from inspect import getargspec
def func(aaa=1, bbb="a", ccc=[1,2,3,], ddd=True, eee=False):
pass
args, varargs, keywords, defaults = getargspec(func)
import argparse
parser = argparse.ArgumentParser()
for arg, default in zip(args, defaults):
if type(default) is tuple or type(default) is list:
parser.add_argument(
'--' + arg,
default=default,
type=type(default),
nargs='+'
)
elif type(default) is bool and default:
parser.add_argument(
'--disable_' + arg,
dest=arg,
default=default,
action="store_false"
)
elif type(default) is bool and not default:
parser.add_argument(
'--enable_' + arg,
dest=arg,
default=default,
action="store_true"
)
else:
parser.add_argument(
'--' + arg,
default=default,
type=type(default)
)
Last but not least werden auch Argumente unterstützt, die keine Standardwerte haben. Beachten Sie jedoch, dass dieses Argument als Zeichenfolge erkannt wird, da sein Typ unbekannt ist.
from inspect import getargspec
def func(x, aaa=1, bbb="a", ccc=[1,2,3,], ddd=True, eee=False):
pass
args, varargs, keywords, defaults = getargspec(func)
print 'args: ', args
print 'varargs', varargs
print 'keywords: ', keywords
print 'defaults: ', defaults
parser = argparse.ArgumentParser()
while len(args) > len(defaults):
l = list(defaults)
l.insert(0, None)
defaults = tuple(l)
for arg, default in zip(args, defaults):
if default is None:
parser.add_argument(dest=arg)
elif type(default) is tuple or type(default) is list:
parser.add_argument(
'--' + arg,
default=default,
type=type(default),
nargs='+'
)
elif type(default) is bool and default:
parser.add_argument(
'--disable_' + arg,
dest=arg,
default=default,
action="store_false"
)
elif type(default) is bool and not default:
parser.add_argument(
'--enable_' + arg,
dest=arg,
default=default,
action="store_true"
)
else:
parser.add_argument(
'--' + arg,
default=default,
type=type(default)
)
print parser.parse_args()
Durch die Verwendung von inspect und argparse war es möglich, das Argument der Funktion automatisch auf das Argument von argparse zu setzen. Die endgültige Version des Codes ist unten beigefügt.
extract_arguments.py
#!/usr/bin/env python
import argparse
from inspect import getargspec
def set_arguments(parser, func):
args, varargs, keywords, defaults = getargspec(func)
print 'args: ', args
print 'varargs', varargs
print 'keywords: ', keywords
print 'defaults: ', defaults
while len(args) > len(defaults):
l = list(defaults)
l.insert(0, None)
defaults = tuple(l)
for arg, default in zip(args, defaults):
if default is None:
parser.add_argument(dest=arg)
elif type(default) is tuple or type(default) is list:
parser.add_argument(
'--' + arg,
default=default,
type=type(default),
nargs='+'
)
elif type(default) is bool and default:
parser.add_argument(
'--disable_' + arg,
dest=arg,
default=default,
action="store_false"
)
elif type(default) is bool and not default:
parser.add_argument(
'--enable_' + arg,
dest=arg,
default=default,
action="store_true"
)
else:
parser.add_argument(
'--' + arg,
default=default,
type=type(default)
)
return parser
def func(x, aaa=1, bbb="a", ccc=[1,2,3,], ddd=True, eee=False):
pass
parser = argparse.ArgumentParser()
parser = set_arguments(parser, func)
print parser.parse_args()
Die folgenden Dekoratoren dienen der Vereinfachung.
register_arguments.py
#!/usr/bin/env python
import argparse
from inspect import getargspec
def register_arguments(parser, func):
args, varargs, keywords, defaults = getargspec(func)
while len(args) > len(defaults):
l = list(defaults)
l.insert(0, None)
defaults = tuple(l)
for arg, default in zip(args, defaults):
if default is None:
parser.add_argument(dest=arg)
elif type(default) is tuple or type(default) is list:
parser.add_argument(
'--' + arg,
default=default,
type=type(default),
nargs='+'
)
elif type(default) is bool and default:
parser.add_argument(
'--disable_' + arg,
dest=arg,
default=default,
action="store_false"
)
elif type(default) is bool and not default:
parser.add_argument(
'--enable_' + arg,
dest=arg,
default=default,
action="store_true"
)
else:
parser.add_argument(
'--' + arg,
default=default,
type=type(default)
)
return parser
def register_argparse(parser):
def wrapper(f):
register_arguments(parser, f)
return f
return wrapper
if __name__ == '__main__':
parser = argparse.ArgumentParser()
@register_argparse(parser)
def func(x, aaa=1, bbb="a", ccc=[1,2,3,], ddd=True, eee=False):
pass
print parser.parse_args()
Wenn das obige ausgeführt wird, wird die folgende Ausgabe ausgegeben.
$ python ./register_argments.py a
Namespace(aaa=1, bbb='a', ccc=[1, 2, 3], ddd=True, eee=False, x='a')
Recommended Posts