Você pode até mesmo usá-lo para gerar um namedtuplecom valores padrão None- tudo em quatro linhas!
Arg_list= collections.namedtuple('Arg_list', arg_names)
args =Arg_list(*(args.get(arg,None)for arg in arg_names))
Caso você não esteja familiarizado namedtuple, é apenas uma tupla que atua como um objeto, permitindo que você acesse seus valores usando tup.attributesintaxe em vez de tup[0]sintaxe.
Portanto, a primeira linha cria um novo namedtupletipo com valores para cada um dos valores em arg_names. A segunda linha passa os valores do argsdicionário, usando getpara retornar um valor padrão quando o nome do argumento fornecido não tem um valor associado no dicionário.
Eu amo Python cada vez mais, tudo graças a respostas como essa e Stack Overflow, é claro! Pena que não temos uma explicação das duas últimas linhas. Eu acredito que para iniciantes isso seria ótimo.
Goujon
2
Adoro! É facilmente a melhor solução que já vi para esse problema. Para outros: Não foi imediatamente óbvio para mim (newb) que: 1) o 'comando' passará como o primeiro argumento a cada vez e 2) você pode chamar os resultados com args [0] etc.
Matt D
Isso é legal com certeza, mas o que há de errado em testar o comprimento?
colorlace de
1
@timwiz eu estava falando apenas em comparação ao uso de argparse. Ainda assim, hoje em dia, eu me chuto toda vez que volto a um script antigo e descubro que não usei argparse.
remetente em
116
Verifique o comprimento de sys.argv:
if len(sys.argv)>1:
blah = sys.argv[1]else:
blah ='blah'
Algumas pessoas preferem a abordagem baseada em exceções que você sugeriu (por exemplo, try: blah = sys.argv[1]; except IndexError: blah = 'blah'), mas eu não gosto tanto porque ela não "escala" tão bem (por exemplo, quando você quer aceitar dois ou três argumentos) e pode potencialmente ocultar erros (por exemplo, se você usou blah = foo(sys.argv[1]), mas foo(...)levantou um IndexError, isso IndexErrorseria ignorado).
Enquanto você estiver sendo atômico sobre isso, não há nada com que se preocupar try, except. Apenas espere fooseu argumento até a elsecláusula.
remetente
3
Além disso, quando você estiver pensando em dimensionar, é hora de passar para argparse.
remetente em
1
+1 em argparse. Eu tenho argparse.pyem todos os meus projetos de linha de comando.
David Wolever
2
@senderle: claro, se você for diligente sobre isso, tudo bem. Mas, na minha experiência, a maioria dos programadores não são diligentes e colocam toda a lógica na trycláusula ... Então, dado que não é mais difícil (e, IMO, um pouco mais bonito), prefiro apenas verificar o comprimento (também, você evita ter pessoas gritar com você por usar exceções para controle de fluxo).
David Wolever
2
@David, sim, entendo seu ponto de vista. Sou um pouco tryapologista, devo admitir. Só sinto que às vezes expressa minha intenção com mais clareza do que uma ifdeclaração.
remetente
22
Outra maneira que ainda não vi na lista é definir o valor de sentinela com antecedência. Este método tira proveito da avaliação preguiçosa do Python, na qual você nem sempre precisa fornecer uma elseinstrução. Exemplo:
A resposta da operadora ternária é a meus olhos a mais bonita. Estou sentado aqui amaldiçoando silenciosamente o fato de que alguns dos softwares que mantenho estão vinculados ao Python 2.4, que não tem.
Isso não é para verificar se definido. É mais como definir se existe, o que não é o mesmo. Usei essa forma também para avaliar variáveis de fallback, mas não é uma resposta à pergunta atual.
m3nda
@ erm3nda Posso remover a startingpointvariável do exemplo, mas a questão é atribuir uma variável de fallback, então acabei de fazer o mesmo.
anatoly techtonik
1
Se você removê-lo, obterá um erro sobre a variável não definida. Li novamente a pergunta, e o que ele espera é uma substituição de variável :) então está tudo bem. Obrigado pelo conselho desse caminho curto se sys.argv[1:]:. Isso funciona com argumentos posicionais, enquanto a contagem não.
m3nda de
10
É uma lista comum do Python. A exceção que você capturaria para isso é IndexError, mas é melhor verificar apenas o comprimento.
if len(sys.argv)>=2:
startingpoint = sys.argv[1]else:
startingpoint ='blah'
Respostas:
No final, a diferença entre
try, except
e o testelen(sys.argv)
não é tão significativa. Ambos são um pouco hackeados em comparação comargparse
.Isso me ocorre, porém - como uma espécie de argumento de baixo orçamento:
Você pode até mesmo usá-lo para gerar um
namedtuple
com valores padrãoNone
- tudo em quatro linhas!Caso você não esteja familiarizado
namedtuple
, é apenas uma tupla que atua como um objeto, permitindo que você acesse seus valores usandotup.attribute
sintaxe em vez detup[0]
sintaxe.Portanto, a primeira linha cria um novo
namedtuple
tipo com valores para cada um dos valores emarg_names
. A segunda linha passa os valores doargs
dicionário, usandoget
para retornar um valor padrão quando o nome do argumento fornecido não tem um valor associado no dicionário.fonte
Verifique o comprimento de
sys.argv
:Algumas pessoas preferem a abordagem baseada em exceções que você sugeriu (por exemplo,
try: blah = sys.argv[1]; except IndexError: blah = 'blah'
), mas eu não gosto tanto porque ela não "escala" tão bem (por exemplo, quando você quer aceitar dois ou três argumentos) e pode potencialmente ocultar erros (por exemplo, se você usoublah = foo(sys.argv[1])
, masfoo(...)
levantou umIndexError
, issoIndexError
seria ignorado).fonte
try, except
. Apenas esperefoo
seu argumento até aelse
cláusula.argparse
.argparse.py
em todos os meus projetos de linha de comando.try
cláusula ... Então, dado que não é mais difícil (e, IMO, um pouco mais bonito), prefiro apenas verificar o comprimento (também, você evita ter pessoas gritar com você por usar exceções para controle de fluxo).try
apologista, devo admitir. Só sinto que às vezes expressa minha intenção com mais clareza do que umaif
declaração.Outra maneira que ainda não vi na lista é definir o valor de sentinela com antecedência. Este método tira proveito da avaliação preguiçosa do Python, na qual você nem sempre precisa fornecer uma
else
instrução. Exemplo:Ou se você usar a sintaxe CRAZY, poderá usar o operador ternário do Python :
fonte
Eu uso isso - nunca falha:
fonte
startingpoint
variável do exemplo, mas a questão é atribuir uma variável de fallback, então acabei de fazer o mesmo.sys.argv[1:]:
. Isso funciona com argumentos posicionais, enquanto a contagem não.É uma lista comum do Python. A exceção que você capturaria para isso é IndexError, mas é melhor verificar apenas o comprimento.
fonte
Uma solução que trabalha com função de mapa embutido!
Então você só precisa chamar seus parâmetros desta forma:
fonte
Você pode simplesmente anexar o valor de argv [1] a argv e, em seguida, verificar se argv [1] não é igual à string inserida. Exemplo:
fonte
Muito perto do que o criador estava tentando fazer. Aqui está uma função que uso:
Portanto, um uso seria algo como:
fonte