En Python tengo un módulo myModule.py donde defino algunas funciones y un main () , que toma algunos argumentos de línea de comando.
Normalmente llamo a esto main () desde un script bash. Ahora, me gustaría poner todo en un paquete pequeño , así que pensé que tal vez podría convertir mi simple script bash en un script Python y ponerlo en el paquete.
Entonces, ¿cómo llamo realmente a la función main () de myModule.py desde la función main () de MyFormerBashScript.py? ¿Puedo siquiera hacer eso? ¿Cómo le paso algún argumento ?

myModule.main(). ¿Qué has intentado hasta ahora?subprocessmódulo?Respuestas:
Es solo una función. Importarlo y llamarlo:
import myModule myModule.main()Si necesita analizar argumentos, tiene dos opciones:
Analizarlos
main(), pero pasarlossys.argvcomo un parámetro (todo el código a continuación en el mismo módulomyModule):def main(args): # parse arguments using optparse or argparse or what have you if __name__ == '__main__': import sys main(sys.argv[1:])Ahora puede importar y llamar
myModule.main(['arg1', 'arg2', 'arg3'])desde otro módulo.Tener
main()aceptar parámetros que ya son analizadas (de nuevo todo el código en elmyModulemó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 importar y llamar a
myModule.main(foovalue, barvalue, baz='ham')otro lugar y pasar argumentos de Python según sea necesario.El truco aquí es detectar cuándo se está utilizando su módulo como script; cuando ejecuta un archivo de Python como el script principal (
python filename.py) noimportse usa ninguna declaración, por lo que Python llama a ese módulo"__main__". Pero si ese mismofilename.pycódigo se trata como un módulo (import filename), Python lo usa como el nombre del módulo. En ambos casos, la variable__name__está configurada y la prueba con ella le indica cómo se ejecutó su código.fuente
argparse, así que cuando llamo al script desde una terminal, lo hago$ python myModule -a input_a -b input_b --parameterC input_c. ¿Cómo funcionaría desde dentro del código Python? Eso es lo que no pude encontrar con una simple búsqueda.La respuesta de Martijen tiene sentido, pero faltaba algo crucial que puede parecer obvio para los demás, pero que fue difícil de entender para mí.
En la versión donde usa argparse, necesita tener esta línea en el cuerpo principal.
Normalmente, cuando usa argparse solo en un script, solo escribe
y parse_args encuentran los argumentos de la línea de comando. Pero en este caso, la función principal no tiene acceso a los argumentos de la línea de comandos, por lo que debe decirle a argparse cuáles son los argumentos.
Aquí hay un ejemplo
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:])Suponiendo que nombró a esto mytest.py Para ejecutarlo, puede hacer cualquiera de estos desde la línea de comando
python ./mytest.py -x 8 python ./mytest.py -x 8 -y 2 python ./mytest.pyque regresa respectivamente
X center: 8.0 Y center: 4o
X center: 8.0 Y center: 2.0o
X center: 2 Y center: 4O si desea ejecutar desde otro script de Python, puede hacerlo
import mytest mytest.main(["-x","7","-y","6"])que regresa
X center: 7.0 Y center: 6.0fuente
AttributeError: module 'sqlacodegen' has no attribute 'main'Depende. Si el código principal está protegido por un
ifcomo en:if __name__ == '__main__': ...main code...entonces no, no puede hacer que Python ejecute eso porque no puede influir en la variable automática
__name__.Pero cuando todo el código está en una función, es posible que pueda hacerlo. Tratar
import myModule myModule.main()Esto funciona incluso cuando el módulo se protege con un
__all__.from myModule import *puede que no seamainvisible para usted, por lo que realmente necesita importar el módulo.fuente
import sys; module.main(sys.argv);__main__que me ayudó, gracias @AaronDigullaYo también tenía la misma necesidad de usar
argparse. La cosa esparse_argsfunción de unaargparse.ArgumentParserinstancia de objeto implícitamente toma sus argumentos por defecto desys.args. La solución, siguiendo la línea de Martijn, consiste en hacer eso explícito, para que pueda cambiar los argumentos a los que pasaparse_argscomo deseo.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:])El punto clave es pasar argumentos para
parse_argsfuncionar. Más tarde, para usar el main, haz lo que te diga Martijn.fuente
La respuesta que estaba buscando fue respondida aquí: ¿Cómo usar python argparse con argumentos distintos de sys.argv?
Si
main.pyyparse_args()está escrito de esta manera, entonces el análisis se puede hacer muy bien# 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)Luego puede llamar
main()y analizar argumentos conparser.parse_args(['--input', 'foobar.txt'])él en otro script de 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)fuente
Suponiendo que también está intentando pasar los argumentos de la línea de comandos.
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:])fuente
argparselugar desys.argv. ¿Cómo cambiaría en este caso? Además, desde el script externo solo quiero pasar algunos argumentos de entrada que el usuario escribe, mientras que otros argumentos de entrada para el script interno (myModule.py) están codificados por mí.*desempaqueta una matrizf(a) => f([1,2,3])frente a lof(*a) => f(1,2,3)que podría hacer con la misma facilidadmyModule.main(sys.argv[1], "other value", 39)o lo que sea.