Jump to content
Sign in to follow this  
rolando2424

[Python] [PyTeam] Como passar argumentos através da linha de comandos aos programas

Recommended Posts

rolando2424

NOTA: Se calhar este tutorial é mais virado para pessoas que usam Linux, devido ao facto de este tutorial ser sobre a linha de comandos, e o pessoal do Windows raramente usa o "cmd" (que também é uma treta, usem mas é o cygwin :D ). De qualquer modo, este tutorial também é aplicável às pessoas que querem escrever programas que corram da linha de comandos, em vez de perderem tempo a criarem um GUI :) .

Toda a gente (ou pelo menos a maior parte), que faz programas que correm da linha de comandos, necessita por vezes de passar argumentos quando executa um ficheiro (por exemplo "firefox -new-tab http://www.portugal-a-programar.org/forum/index.php").

Mas como é que se faz isso em Python?

Na realidade, existem 3 maneiras de o fazer. Iremos começar pela mais simples que é usando o módulo sys.

import sys

argumentos_passados = sys.argv[1:]

print argumentos_passados

O sys.argv é uma lista, que contém tudo o que é escrito quando o programa é iniciado (já vou explicar a razão para usar o [1:], ou seja, não contar com o primeiro valor) . Por exemplo, se gravarem este código num ficheiro (digamos, python_sys.py), e começarem a escrever coisas para a frente, o resultado que irão obter será aquilo que escreveram. Por exemplo:

rolando@rolando-desktop:~/Desktop$ python python_sys.py

[]

rolando@rolando-desktop:~/Desktop$

Isto é o que obtemos quando executamos o programa, mas sem lhe passar nenhuns argumentos, ele não imprime nada, pois não lhe passamos nada.

Agora vamos tentar outra vez.

rolando@rolando-desktop:~/Desktop$ python python_sys.py -v -e --dir ~/Desktop/porn

['-v', '-e', '--dir', '/home/rolando/Desktop/porn']

rolando@rolando-desktop:~/Desktop$

Como podem ver, recebemos uma lista com os atributos todos que passamos.

Mas é o que é o sys.argv[0]? Bem, isso é o nome do ficheiro! Para vermos isso, vamos modificar o programa um pouco.

import sys

nome_do_ficheiro = sys.argv[0]

argumentos_passados = sys.argv[1:]

print "O nome do ficheiro e: " + nome_do_ficheiro
print "E os argumentos passados sao: " + str(argumentos_passados)

NOTA: Lembrem-se que os argumentos_passados são uma lista, e por isso não podem adicionar directamente a uma string sem o converter primeiro para uma string também.

E agora vamos correr o programa.

rolando@rolando-desktop:~/Desktop$ python python_sys.py

O nome do ficheiro e: python_sys.py

E os argumentos passados sao: []

rolando@rolando-desktop:~/Desktop$

Se passarmos alguns argumentos, o efeito será como anteriormente.

rolando@rolando-desktop:~/Desktop$ python python_sys.py -v -e --dir ~/Desktop/porn

O nome do ficheiro e: python_sys.py

E os argumentos passados sao: ['-v', '-e', '--dir', '/home/rolando/Desktop/porn']

rolando@rolando-desktop:~/Desktop$

E se mudarmos o nome do ficheiro do programa?

rolando@rolando-desktop:~/Desktop$ mv python_sys.py o_meu_programa_leet.py

rolando@rolando-desktop:~/Desktop$ python o_meu_programa_leet.py

O nome do ficheiro e: o_meu_programa_leet.py

E os argumentos passados sao: []

rolando@rolando-desktop:~/Desktop$

Como podem ver, sempre que mudam o nome do ficheiro, o sys.argv[0] mudará também.

Apesar de o sys.argv ser o método mais simples de obter os argumentos, trabalhar com eles pode não ser o mais fácil. Basicamente terão que ter um for loop do estilo:

for argumento in range(0, len(argumentos_passados)):
   if argumentos_passados[argumento] == "-v":
       verbose = True

   if argumentos_passados[argumento] == "-e":
       export()

   if argumentos_passados[argumento] == "--dir" \
   and argumentos_passados[argumento + 1][0] != "-" \
   and argumentos_passados[argumento + 1][:1] != "--":
       directorio = argumento_passado[argumento + 1]

Depois do sys.argv, temos o módulo getopt. Infelizmente, nunca o usei muito, por isso o melhor é vocês verem a documentação oficial para o módulo aqui

Assim que tiver mais experiência, eu irei adicionar-lo ao tutorial.

Por fim, o outro método é usar o OptionParser, que está no módulo optparse, que é um método mais Object-Oriented.

from optparse import OptionParser

argv = OptionParser()

argv.add_option("-v", "--verbose", action = "store_true", dest = "verbose",
                   help = "Faz o programa mostrar mais informacao")

argv.add_option("-d", "--dir", action = "store", dest = "directorio", type ="string",
                   help = "Guarda o directorio")

(argumentos, palha_que_nao_interessa) = argv.parse_args()

Este método é diferente do outro, mas é também simples. Primeiro de tudo, temos que associar o OptionParser() a uma variável (neste caso, argv). Depois, vamos dando as nossas opções a essa variável, usando o método "add_option" e dizendo a opção que queremos nomear (por exemplo, "-v" ou "-d"), com a opção de dar-mos um argumento longo (daqueles que começam com "--"). Depois dissemos o que queremos fazer quando usarmos essa opção (por exemplo, "store_true", que faz com que uma variável tenha o valor True, ou o "store" que faz com que o valor que vier à frente seja guardado numa variável (exemplo: "-d ~/Desktop/porn" guarda o "~/Desktop/porn" numa variável)). Depois podemos dar o destino para onde queremos colocar o valor da opção (por exemplo, o True), para depois podermos aceder a ela (já explico como aceder às variáveis). Por fim, podemos definir uma mensagem de ajuda, pois o OptionParser cria automaticamente um argumento "-h" ou "--help", que mostra automaticamente, todas as strings "help" definidas.

Por fim, temos de usar o método "parse_args" em duas variáveis, para podermos aceder às opções.

A primeira variável (neste caso, "argumentos"), vai receber o valor das opções que encontrar. Por exemplo, se quiséssemos aceder ao valor da opção "-v" víamos que o seu destino é "verbose", logo para acedermos a ela, tínhamos que usar "argumentos.verbose", sendo que o mesmo seria para o "-d" (ou seja, "argumentos.directorio"). Caso exista opções passadas ao executar o programa, e que não tenham sido definidas pelo método "add_option", essas opções irão para a segunda variável (neste caso, convenientemente chamada de "palha_que_nao_interessa").

Sendo assim, caso corrermos o programa com as opções "--dir ~/Desktop/porn --eu_nao_existo", a variável "argumentos.directorio" teria o valor "~/Desktop/porn" e caso usassem um print na variável "palha_que_nao_interessa", veriam que a opção "--eu_nao_existo", estava lá, pois o programa não sabe o que fazer com ela.

O módulo ObjectParser, contém mais algumas opções, que podem ver aqui (contém um tutorial e tudo :D ).

Sendo assim, qual será a melhor opção a utilizar, da próxima vez que vocês tiveram a fazer um programa e queiram dar um funcionalidade na linha de comandos? Na minha opinião isso depende.

Caso queiram uma coisa mais rápida, e sem terem que se preocupar muito com a ordem com que os argumentos são dados, o melhor seria irem com o OptionParser.

Se no entanto, quiserem mais controlo sobre as opções, e não se importam de codar todas as pequenas coisas, acho que seria melhor usarem o sys.argv (penso que oferece um maior controlo sobre as opções).

E assim acabamos o tutorial.


Não me responsabilizo por qualquer dano ocorrido no seguimento dos meus conselhos. Prontos, a minha pessoa está oficialmente protegida legalmente :D

Share this post


Link to post
Share on other sites
rolando2424

Ainda bem que te ajudou ;)

(Só tenho é que aprender a mexer mais no getopt, para depois adicionar aqui :()


Não me responsabilizo por qualquer dano ocorrido no seguimento dos meus conselhos. Prontos, a minha pessoa está oficialmente protegida legalmente :D

Share this post


Link to post
Share on other sites
Felix_Poison

Belissimo artigo, Rolando2424

(eita que nick estranho, amigo! HUAHAUHAUHAUAHUAHAUHAU

Brincadeirinha rs..  :thumbsup:

Thanks

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.