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()
È stato utile?

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:

     
      
  1. parser :. L'oggetto ArgumentParser che contiene questa azione
  2.   
  3. 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.
  4.   
  5. 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()
  6.   
  7. 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.
  8.   

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 a set_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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top