Em Python, tenho um módulo myModule.py onde defino algumas funções e um main () , que leva alguns argumentos de linha de comando.
Normalmente chamo isso de main () de um script bash. Agora, gostaria de colocar tudo em um pequeno pacote , então pensei que talvez pudesse transformar meu script bash simples em um script Python e colocá-lo no pacote.
Então, como eu realmente chamo a função main () de myModule.py a partir da função main () de MyFormerBashScript.py? Posso fazer isso? Como posso passar argumentos para ele?
myModule.main()
. O que você tentou até agora?subprocess
módulo?Respostas:
É apenas uma função. Importe-o e chame-o de:
import myModule myModule.main()
Se precisar analisar argumentos, você tem duas opções:
Analise-os
main()
, mas passe-ossys.argv
como um parâmetro (todos os códigos abaixo no mesmo módulomyModule
):def main(args): # parse arguments using optparse or argparse or what have you if __name__ == '__main__': import sys main(sys.argv[1:])
Agora você pode importar e chamar
myModule.main(['arg1', 'arg2', 'arg3'])
de outro módulo.Ter
main()
parâmetros de aceitação que já foram analisados (novamente, todo o código nomyModule
módulo):def main(foo, bar, baz='spam'): # run with already parsed arguments if __name__ == '__main__': import sys # parse sys.argv[1:] using optparse or argparse or what have you main(foovalue, barvalue, **dictofoptions)
e importe e chame em
myModule.main(foovalue, barvalue, baz='ham')
outro lugar e passe argumentos Python conforme necessário.O truque aqui é detectar quando seu módulo está sendo usado como um script; quando você executa um arquivo python como o script principal (
python filename.py
), nenhumaimport
instrução está sendo usada, portanto, o python chama esse módulo"__main__"
. Mas se esse mesmofilename.py
código for tratado como um módulo (import filename
), então o python usa isso como o nome do módulo. Em ambos os casos, a variável__name__
é definida e o teste em relação a isso informa como seu código foi executado.fonte
argparse
, então, quando chamo o script de um terminal, eu uso$ python myModule -a input_a -b input_b --parameterC input_c
. Como funcionaria de dentro do código python? Isso é o que não consegui encontrar em uma pesquisa simples.A resposta de Martijen faz sentido, mas estava faltando algo crucial que pode parecer óbvio para os outros, mas era difícil para mim descobrir.
Na versão em que você usa argparse, você precisa ter esta linha no corpo principal.
Normalmente, quando você está usando argparse apenas em um script, você acabou de escrever
e parse_args encontra os argumentos da linha de comando. Mas, neste caso, a função principal não tem acesso aos argumentos da linha de comando, então você deve informar ao argparse quais são os argumentos.
Aqui está um exemplo
import argparse import sys def x(x_center, y_center): print "X center:", x_center print "Y center:", y_center def main(args): parser = argparse.ArgumentParser(description="Do something.") parser.add_argument("-x", "--xcenter", type=float, default= 2, required=False) parser.add_argument("-y", "--ycenter", type=float, default= 4, required=False) args = parser.parse_args(args) x(args.xcenter, args.ycenter) if __name__ == '__main__': main(sys.argv[1:])
Supondo que você tenha nomeado este mytest.py Para executá-lo, você pode fazer qualquer um destes na linha de comando
python ./mytest.py -x 8 python ./mytest.py -x 8 -y 2 python ./mytest.py
que retorna respectivamente
X center: 8.0 Y center: 4
ou
X center: 8.0 Y center: 2.0
ou
X center: 2 Y center: 4
Ou se você deseja executar a partir de outro script Python, você pode fazer
import mytest mytest.main(["-x","7","-y","6"])
que retorna
X center: 7.0 Y center: 6.0
fonte
AttributeError: module 'sqlacodegen' has no attribute 'main'
Depende. Se o código principal estiver protegido por um
if
as in:if __name__ == '__main__': ...main code...
então não, você não pode fazer o Python executar isso porque você não pode influenciar a variável automática
__name__
.Mas quando todo o código está em uma função, talvez seja possível. Experimentar
import myModule myModule.main()
Isso funciona mesmo quando o módulo se protege com um
__all__
.from myModule import *
pode não ficarmain
visível para você, então você realmente precisa importar o próprio módulo.fonte
import sys; module.main(sys.argv);
__main__
que me ajudou, obrigado @AaronDigullaTive a mesma necessidade de usar
argparse
também. A coisa éparse_args
função de umaargparse.ArgumentParser
instância de objeto implicitamente recebe seus argumentos por padrão desys.args
. A solução, seguindo a linha de Martijn, consiste em tornar isso explícito, para que você possa alterar os argumentos que passaparse_args
como desejo.def main(args): # some stuff parser = argparse.ArgumentParser() # some other stuff parsed_args = parser.parse_args(args) # more stuff with the args if __name__ == '__main__': import sys main(sys.argv[1:])
O ponto principal é passar argumentos para a
parse_args
função. Depois, para usar o principal, basta fazer o que Martijn manda.fonte
A resposta que eu estava procurando foi respondida aqui: Como usar python argparse com args diferente de sys.argv?
Se
main.py
eparse_args()
for escrito desta forma, a análise pode ser feita de forma adequada# main.py import argparse def parse_args(): parser = argparse.ArgumentParser(description="") parser.add_argument('--input', default='my_input.txt') return parser def main(args): print(args.input) if __name__ == "__main__": parser = parse_args() args = parser.parse_args() main(args)
Em seguida, você pode chamar
main()
e analisar argumentos comparser.parse_args(['--input', 'foobar.txt'])
ele em outro script Python:# temp.py from main import main, parse_args parser = parse_args() args = parser.parse_args([]) # note the square bracket # to overwrite default, use parser.parse_args(['--input', 'foobar.txt']) print(args) # Namespace(input='my_input.txt') main(args)
fonte
Supondo que você esteja tentando passar os argumentos da linha de comando também.
import sys import myModule def main(): # this will just pass all of the system arguments as is myModule.main(*sys.argv) # all the argv but the script name myModule.main(*sys.argv[1:])
fonte
argparse
vez desys.argv
. Como isso mudaria neste caso? Além disso, do script externo, quero apenas passar alguns argumentos de entrada que o usuário digita, enquanto outros argumentos de entrada para o script interno (myModule.py) são codificados por mim.*
descompacta um arrayf(a) => f([1,2,3])
vsf(*a) => f(1,2,3)
Você poderia facilmente fazermyModule.main(sys.argv[1], "other value", 39)
ou qualquer outra coisa.