Uso dell'uscita argparse chiamare funzioni
-
27-09-2019 - |
Domanda
Al momento il mio codice simile a questo. Mi permette di analizzare più parametri mio script programma ottiene. C'è un modo diverso che è più vicino a 'migliori pratiche'? Non ho visto il codice in realtà utilizzando l'uscita di argparse
, solo come impostarlo.
def useArguments():
x = 0
while x <= 5:
if x == 0:
if args.getweather != None:
getWeather(args.getweather)
if x == 1:
if args.post != None:
post(args.post)
if x == 2:
if args.custompost != None:
custompost(args.custompost)
if x == 3:
if args.list != None:
listAccounts(args.list)
if x == 4:
if args.add != None:
addAccount(args.add[0])
if x == 5:
if args.edit != None:
editAccount(args.edit[0])
x = x + 1
if __name__ == '__main__':
updateConfig()
parser = argparse.ArgumentParser(description='Post Yahoo weather to Twitter.', epilog="Report any bugs to example@email.com", prog='Program')
parser.add_argument('-a', '--add', nargs=1, help='Add a new account. Use the desired account name as an argument.')
parser.add_argument('-e', '--edit', nargs=1, choices=accountListSTR[:-1], help='Edit an account. Use the desired account name as an argument.')
parser.add_argument('-g', '--getweather', nargs='*', choices=accountListSTR, help='Get weather and post here. Specify account(s) as argument. Use "all" for all accounts. If you specify multiple accounts, separate by a space NOT a comma.')
parser.add_argument('-p', '--post', nargs='*', choices=accountListSTR, help='Post weather to Twitter. Specify account(s) as argument. Use "all" for all accounts. If you specify multiple accounts, separate by a space NOT a comma.')
parser.add_argument('-c', '--custompost', nargs=2, help='Post a custom message. Specify an account then type the message. Make sure you use "" around the message. Use "all" for all accounts.')
parser.add_argument('-l', '--list', action='store_const', const='all', help='List all accounts.')
parser.add_argument('--version', action='version', version='%(prog)s 0.3.3')
args = parser.parse_args()
useArguments()
Soluzione
Si potrebbe fornire un costume azione per un argomento da, ed io quote:
passaggio di un oggetto che implementa le API Azione. Il modo più semplice per fare questo è estendere argparse.Action, fornendo un appropriato
__call__
metodo. Il metodo dovrebbe__call__
accetta quattro parametri:
- parser :. L'oggetto ArgumentParser che contiene questa azione
- namespace : l'oggetto dello spazio dei nomi che verrà restituito da
parse_args()
. La maggior parte delle azioni di aggiungere un attributo a questo oggetto.- valori :.. Gli argomenti della riga di comando associati per qualunque tipo conversioni applicati (Type-conversioni sono specificati con il tipo di parola chiave argomento
add_argument()
- option_string : La stringa opzione che è stato utilizzato per richiamare questa azione. L'argomento option_string è opzionale, e sarà assente se l'azione è associata con un argomento posizionale.
Altri suggerimenti
http://docs.python.org/library/argparse.html # comandi secondari :
Un modo particolarmente efficace di gestire comandi secondari è quello di combinare l'uso del metodo
add_subparsers()
con chiamate aset_defaults()
modo che ogni subparser sa quale funzione Python dovrebbe eseguire.
In poche parole:
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
weather_parser = subparsers.add_parser('get-weather')
weather_parser.add_argument('--bar')
weather_parser.set_defaults(function=get_weather) # !
args = parser.parse_args(['get-weather', '--bar', 'quux'])
print args.function(args)
Qui creiamo un subparser per il comando get-weather
e assegnare la funzione get_weather
ad esso.
Si noti che la documentazione dice che la parola / attributo è chiamato func
ma è sicuramente function
come di argparse 1.1.
Il codice risultante è un po 'troppo prolisso così ho pubblicato un piccolo pacchetto "argh" che rende le cose più semplici, ad esempio:
parser = argparse.ArgumentParser()
add_commands(parser, [get_weather])
print dispatch(parser, ['get-weather', '--bar', 'quux'])
"Argh" può fare di più, ma vi svelo risposta overflow dello stack che. : -)
Con l'eccezione di --version
, che è molto comunemente un'opzione, le azioni che hai fornito sono meglio trattati come "sottocomandi".
Sono a conoscenza delle specifiche argparse, come devo ancora provare Python 2.7, ma si potrebbe dare un'occhiata al comando svn
come un esempio, ecco qualche pseudocodice per la riga di comando:
myprog [--version] <command> [<command opts>...]
Dove <command>
in:
add|edit|getweather|post|custompost|list
E <command opts>
sono soluzioni specifiche per quel comando. Utilizzando optparse (che è simile), questo significherebbe che il vostro comando sarebbe tornato in args
, quando si chiama parse_args
, che consente di fare qualcosa di simile:
opts, args = parser.parse_args()
if opts.version:
...
else:
getattr("do_" + args[0])(*args[1:])
Trovo che questo modello particolarmente utile per il debug, dove mi piacerebbe fornire l'accesso alle funzioni interne dalla riga di comando, e passare vari argomenti per testare. Regolare la selezione del gestore di comandi come appropriato per il proprio progetto.