2010-10-28 22 views
400

Duplicar posible:
What does if __name__== "__main__" do?¿Por qué usar def main()?

he visto algunos ejemplos de código y tutoriales que utilizan

def main(): 
    # my code here 

if __name__ == "__main__": 
    main() 

Pero por qué? ¿Hay alguna razón para no definir tus funciones en la parte superior del archivo, y luego simplemente escribir el código debajo de él? es decir,

def my_function() 
    # my code here 

def my_function_two() 
    # my code here 

# some code 
# call function 
# print(something) 

Me pregunto si hay algo de rima en la canción principal?

+2

Ver http://stackoverflow.com/questions/419163/what-does-if-name-main-do – gimel

+8

stackoverflow.com/questions/419163/what-does-if-name-main-do does no responde toda la pregunta – Johnsyweb

+4

Lo que el supuesto duplicado no responde: tener una función main() (en lugar de simplemente escribir todo el código en el bloque "if __name__") es útil porque evita crear accidentalmente variables globales que podrían afectar a otras funciones. – slowdog

Respuesta

465

Sin el centinela principal, el código se ejecutará incluso si el script se importó como un módulo.

+121

También vale la pena señalar que tener un La función 'main()' hace posible ejecutar ese código con: 'import module; module.main() '. Si el código estaba solo en el bloque 'if', no podría ejecutarse desde otro lugar. – FogleBird

7

Considere la segunda secuencia de comandos. Si lo importa en otro, las instrucciones, como en "nivel global", se ejecutarán.

72

si el contenido de foo.py

print __name__ 
if __name__ == '__main__': 
    print 'XXXX' 

Un foo.py archivo se puede utilizar de dos maneras.

  • importados en otro archivo: import foo

En este caso __name__ es foo, la sección de código no se ejecuta y no se imprime XXXX.

  • ejecutados directamente: python foo.py

Cuando se ejecuta directamente, __name__ es igual que __main__ y se ejecuta el código en esa sección y grabados XXXX

Uno de los usos de esta funcionalidad para escribir varios tipos de pruebas unitarias dentro del mismo módulo.

+0

Aunque esta respuesta es menos votada que algunas otras, pero lo explicó muy claro. Leí [esta respuesta] (http://stackoverflow.com/a/419185/2455888) antes, pero se ha explicado bien. +1 – haccks

15

"What does if __name__==“__main__”: do?" ya se ha respondido.

Tener una funciónmain()le permite llamar a su funcionalidad si import el módulo. El beneficio principal (sin juego de palabras) de esto (en mi humilde opinión) es que usted puede probarlo en una unidad.

+1

2 preguntas con la misma respuesta no las hace duplicadas – bubakazouba

+3

@bubakazouba: Estoy de acuerdo. No marqué esta pregunta como un duplicado. * Una parte * de esta pregunta tiene una muy buena respuesta, no tuve sentido duplicar la respuesta. Respondí * el resto * de la pregunta. – Johnsyweb

183

Todos los demás ya lo han respondido, pero creo que todavía tengo algo más que agregar.

razones para tener que if declaración llamando main() (en ningún orden en particular):

  • Otros lenguajes (como C y Java) tienen una función main() que se llama cuando se ejecuta el programa. Utilizando este if, podemos hacer que Python se comporte como ellos, lo cual es más familiar para muchas personas.

  • El código será limpiador, más fácil de leer y mejor organizado. (Sí, sé que esto es subjetivo)

  • Será posible import que el código python como un módulo sin efectos secundarios desagradables.

    • Esto significa que será posible ejecutar pruebas en contra de ese código.

    • Esto significa que podemos importar ese código en un shell de python interactivo y probarlo/depurarlo/ejecutarlo.

  • variables dentro def mainson locales, mientras que los que están afuera son mundial. Esto puede introducir algunos errores y comportamientos inesperados.

Pero, ustedes están no requiere escribir una función main() y llamarlo dentro de una sentencia if.

Normalmente, yo mismo empiezo a escribir pequeños scripts desechables sin ningún tipo de función. Si el guión crece lo suficiente, o si siento que poner todo ese código dentro de una función me beneficiará, entonces refactorizaré el código y lo haré. Esto también ocurre cuando escribo scripts bash.

Incluso si coloca el código dentro de la función principal, no es necesario que lo escriba exactamente como eso. Una variación podría ser ordenada:

import sys 

def main(argv): 
    # My code here 
    pass 

if __name__ == "__main__": 
    main(sys.argv) 

Esto significa que puede llamar main() de otros scripts (o shell interactivo) que pasan los parámetros personalizados. Esto podría ser útil en pruebas unitarias o cuando se procesa por lotes. Pero recuerde que el código anterior requerirá un análisis sintáctico de argv, por lo tanto, tal vez sería mejor utilizar una llamada diferente que pase los parámetros ya analizados.

En una aplicación orientada a objetos que he escrito, el código era la siguiente:

class MyApplication(something): 
    # My code here 

if __name__ == "__main__": 
    app = MyApplication() 
    app.run() 

Por lo tanto, no dude en escribir el código que mejor le convenga. :)

+0

Una de las ventajas de llamar 'main' con' sys.argv' como parámetro, como se muestra aquí, es que este enfoque funciona bien con el módulo 'argparse' (que, IMO, es * Right Way * para manejar argumentos de línea de comandos) . Todo lo que necesita hacer de otra manera es pasar 'argv' a' parse_args' en 'main'. – jkt123