1534 votos

¿Qué hace `si __nombre__ == "__main__":`?

¿Qué hace el if __name__ == "__main__": hacer?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while 1:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)
if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

Además, ¿qué hace *args significa en este ejemplo?

1799voto

Mr Fooz Puntos 21092

Ampliando un poco la respuesta de Harley...

Cuando el intérprete de Python lee un archivo fuente, ejecuta todo el código que se encuentra en él. Antes de ejecutar el código, definirá unas cuantas variables especiales. Por ejemplo, si el intérprete de Python está ejecutando ese módulo (el archivo fuente) como el programa principal, establece la variable especial __name__ variable para tener un valor "__main__" . Si este archivo está siendo importado desde otro módulo, __name__ se ajustará al nombre del módulo.

En el caso de tu script, asumamos que se está ejecutando como la función principal, por ejemplo, dijiste algo como

python threading_example.py

en la línea de mando. Después de configurar las variables especiales, ejecutará el import y cargar esos módulos. Luego evaluará la def bloque, creando un objeto de función y creando una variable llamada myfunction que apunta al objeto de la función. Entonces leerá el if y ver que __name__ es igual "__main__" así que ejecutará el bloque que se muestra allí.

Una de las razones para hacer esto es que a veces se escribe un módulo (un .py archivo) donde puede ser ejecutado directamente. También puede ser importado y utilizado en otro módulo. Haciendo la comprobación principal, puedes hacer que ese código sólo se ejecute cuando quieras ejecutar el módulo como un programa y no hacer que se ejecute cuando alguien sólo quiera importar tu módulo y llamar a tus funciones por sí mismo.

Ver esta página para algunos detalles adicionales.

523voto

Adam Rosenfield Puntos 176408

Cuando tu script se ejecuta pasándolo como un comando al intérprete de Python,

python myscript.py

todo el código que está en el nivel de indentación 0 se ejecuta. Las funciones y clases que están definidas están, bueno, definidas, pero no se ejecuta ningún código. A diferencia de otros lenguajes, no hay main() que se ejecuta automáticamente - la main() la función es implícitamente todo el código en el nivel superior.

En este caso, el código de nivel superior es un if bloque. __name__ es una variable incorporada que evalúa al nombre del módulo actual. Sin embargo, si un módulo se está ejecutando directamente (como en myscript.py arriba), entonces __name__ en lugar de ello se establece en la cadena "__main__" . Por lo tanto, puedes probar si tu script se está ejecutando directamente o está siendo importado por otra cosa probando

if __name__ == "__main__":
    ...

Si ese código se importa a otro módulo, se importarán las diversas definiciones de funciones y clases, pero el main() el código no se ejecutará. Como ejemplo básico, considera los siguientes dos scripts:

# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")

# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

Ahora, si invoca al intérprete como

python one.py

La salida será

top-level in one.py
one.py is being run directly

Si corres two.py en su lugar:

python two.py

Usted obtiene

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

Así, cuando el módulo one se carga, su __name__ es igual a "one" en lugar de __main__ .

270voto

pi. Puntos 6026

La explicación más simple para la __name__ variable (imho) es la siguiente:

Crea los siguientes archivos.

# a.py
import b

y

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Ejecutarlas te dará esta salida:

$ python a.py
Hello World from b!

$ python b.py
Hello World from __main__!
Hello World again from __main__!

170voto

Aaron Hall Puntos 7381

Intento responder a la pregunta principal con una explicación lo más completa posible.

Desarrollando y probando su código

Digamos que estás escribiendo un Python script diseñado para ser usado como un módulo:

def do_important():
    '''This function does something very important'''

Usted podría Pruebe el módulo añadiendo esta llamada de la función en la parte inferior:

do_important()

y ejecutándolo con algo como (en un símbolo de comando):

~$ python important.py

El problema

Sin embargo, si quieres importar el módulo a otro script:

import important

En la importación, el do_important se llamaría a la función, así que probablemente comentarías tu llamada a la función en la parte inferior. Y entonces tendrás que recordar si has comentado o no tu llamada a la función de prueba. Y esta complejidad adicional significaría que probablemente lo olvides, haciendo que tu proceso de desarrollo sea más problemático.

Una mejor manera

El __name__ La variable apunta al espacio de nombres donde se encuentra el intérprete de Python en este momento. Dentro de un módulo importado, es el nombre de ese módulo. Pero dentro del módulo primario (o el REPL de un intérprete) desde el que se ejecuta todo, es "__main__" .

Así que si lo compruebas antes de ejecutar:

if __name__ == "__main__":
    do_important()

Con lo anterior, tu código sólo se ejecutará cuando lo estés ejecutando como módulo primario (o lo llames intencionadamente desde otro script).

Una forma aún mejor

Sin embargo, hay una forma Pythonica de mejorar esto.

El código Python puede correr más rápido en una función (ver el enlace para saber cómo y por qué), así que si ponemos el código que queremos ejercitar a medida que desarrollamos y probamos en una función como esta y luego hacemos nuestra comprobación de principal inmediatamente después:

def main():
    '''business logic for when running this module as the primary one!'''
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

Ahora tenemos una función final para el final de nuestro módulo que se ejecutará si ejecutamos el módulo como módulo primario, pero que también permitirá que el módulo y sus funciones y clases se importen a otros scripts sin ejecutar el main funcionan, de la manera más eficiente (si la eficiencia importa).

Este modismo también se puede encontrar (profundo) en la documentación de Python en una explicación de la __main__ módulo. Ese texto dice:

Este módulo representa el ámbito (por lo demás anónimo) en el que el el programa principal del intérprete se ejecuta - los comandos se leen ya sea de entrada estándar, desde un archivo script, o desde un prompt interactivo. Es es este entorno en el que la estrofa idiomática "condicional script" hace que se ejecute un script:

if __name__ == '__main__':
    main()

50voto

Federico A. Ramponi Puntos 23106

La sintaxis *args en una declaración de función permite aceptar un número arbitrario de parámetros (distintos de los nombrados explícitamente, como string , sleeptime y lock en su ejemplo):

def printStuff(*args):
    for arg in args:
        print arg

printStuff(1, 2, "Hello World")

1
2
Hello World

La sintaxis *args en una llamada de función te permite llamar con los elementos de la lista args como argumentos adicionales:

args = [4, 5, "Goodbye"]
printStuff(2, 3, *args)

2
3
4
5
Goodbye

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X