Pergunta

Atualmente, meu código se parece com isso. Isso me permite analisar vários parâmetros que meu script de programa recebe. Existe uma maneira diferente de mais perto das 'melhores práticas'? Eu não vi código realmente usando a saída de argparse, apenas como configurá -lo.

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()
Foi útil?

Solução

Você poderia fornecer um costume ação Para uma discussão, e eu cito:

Passar um objeto que implementa a API de ação. A maneira mais fácil de fazer isso é estender o argparse.action, fornecendo um apropriado __call__método. o __call__ O método deve aceitar quatro parâmetros:

  1. analisador: O objeto ArgumentParser que contém essa ação.
  2. espaço para nome: O objeto de espaço para nome que será devolvido por parse_args(). A maioria das ações adiciona um atributo a esse objeto.
  3. valores: add_argument().
  4. option_string: A sequência de opções que foi usada para invocar esta ação. O argumento Option_String é opcional e estará ausente se a ação estiver associada a um argumento posicional.

Outras dicas

Ver http://docs.python.org/library/argparse.html#sub-commands:

Uma maneira particularmente eficaz de lidar com os subcomandos é combinar o uso do add_subparsers() Método com chamadas para set_defaults() para que cada subparsador saiba qual função python deve ser executada.

Em poucas palavras:

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)

Aqui criamos um subparser para o comando get-weather e atribua a função get_weather para isso.

Observe que a documentação diz que a palavra -chave/atributo é nomeada func Mas é definitivamente function A partir de argparse 1.1.

O código resultante é um pouco muito prolixo, então publiquei um pequeno pacote "Argh" Isso simplifica as coisas, por exemplo:

parser = argparse.ArgumentParser()
add_commands(parser, [get_weather])
print dispatch(parser, ['get-weather', '--bar', 'quux'])

"Argh" pode fazer mais, mas vou deixar o Stack Overflow responder isso. :-)

Com a exceção de --version, que é comumente uma opção, as ações que você forneceu são melhor tratadas como "subcomando".

Não tenho conhecimento dos detalhes do ArgParse, pois ainda não experimentei o Python 2.7, mas você pode dar uma olhada no svn Comando como exemplo, aqui está algum pseudocódigo para a linha de comando:

myprog [--version] <command> [<command opts>...]

Onde <command> dentro:

add|edit|getweather|post|custompost|list

E <command opts> são opções específicas para esse comando. Usando optparse (o que é semelhante), isso significaria que seu comando seria devolvido em args, ao ligar parse_args, permitindo que você faça algo assim:

opts, args = parser.parse_args()
if opts.version:
    ...
else:
    getattr("do_" + args[0])(*args[1:])

Acho esse padrão particularmente útil para a depuração, onde eu forneceria acesso a funções internas da linha de comando e passaria vários argumentos para testes. Ajuste a seleção do manipulador de comando conforme apropriado para seu próprio projeto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top