600 votes

Pourquoi utiliser def main()?

J'ai vu certains exemples de code et tutoriels qui utilisent

def main():
    # mon code ici

if __name__ == "__main__":
    main()

Mais pourquoi? Y a-t-il une raison de ne pas définir vos fonctions en haut du fichier, puis simplement écrire du code en dessous? c'est-à-dire

def my_function()
    # mon code ici

def my_function_two()
    # mon code ici

# un peu de code
# appeler la fonction
# imprimer(quelque chose)

Je me demande juste s'il y a une raison à tout cela?

3 votes

32 votes

Stackoverflow.com/questions/419163/what-does-if-name-main-do ne répond pas à l'ensemble de la question.

12 votes

Ce que le supposé duplicata ne répond pas : avoir une fonction main() (au lieu d'écrire tout le code dans le bloc "if nom") est utile car cela évite de créer accidentellement des variables globales qui pourraient affecter d'autres fonctions.

661voto

Ignacio Vazquez-Abrams Points 312628

Sans le principal point de repère, le code serait exécuté même si le script était importé en tant que module.

184 votes

Il est également intéressant de noter qu'avoir une fonction main() permet d'exécuter ce code avec : import module; module.main(). Si le code se trouvait simplement dans le bloc if, il ne pourrait pas être exécuté depuis un autre endroit.

0 votes

Pourquoi Python ne prend-il pas en charge une fonction principale professionnelle qui est automatiquement exécutée par python code.py ?

264voto

Denilson Sá Points 6953

Tout le monde a déjà répondu, mais je pense quand même avoir quelque chose à ajouter.

Raisons d'avoir cette instruction if appelant main() (sans ordre particulier) :

  • D'autres langages (comme le C et le Java) ont une fonction main() qui est appelée lorsque le programme est exécuté. En utilisant cet if, nous pouvons faire en sorte que Python se comporte comme eux, ce qui est plus familier pour beaucoup de gens.

  • Le code sera plus propre, plus facile à lire et mieux organisé. (oui, je sais que c'est subjectif)

  • Il sera possible d'importer ce code Python en tant que module sans effets secondaires désagréables.

  • Cela signifie qu'il sera possible de faire des tests sur ce code.

  • Cela signifie que nous pouvons importer ce code dans une console interactive Python et le tester/déboguer/exécuter.

  • Les variables à l'intérieur de def main sont locales, tandis que celles à l'extérieur sont globales. Cela peut introduire quelques bugs et comportements inattendus.

Mais, vous n'êtes pas obligé d'écrire une fonction main() et de l'appeler à l'intérieur d'une instruction if.

Personnellement, je commence généralement par écrire de petits scripts temporaires sans aucune fonction. Si le script devient assez gros, ou si je sens que mettre tout ce code dans une fonction me sera profitable, alors je le refactorise et je le fais. Cela arrive aussi lorsque j'écris des scripts bash.

Même si vous mettez du code à l'intérieur de la fonction main, vous n'êtes pas obligé de l'écrire exactement comme ça. Une variation intéressante pourrait être :

import sys

def main(argv):
    # Mon code ici
    pass

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

Cela signifie que vous pouvez appeler main() depuis d'autres scripts (ou une console interactive) en passant des paramètres personnalisés. Cela peut être utile dans des tests unitaires, ou lors du traitement par lot. Mais rappelez-vous que le code ci-dessus nécessitera l'analyse de argv, donc il serait peut-être préférable d'utiliser un autre appel qui passe déjà des paramètres analysés.

Dans une application orientée objet que j'ai écrite, le code ressemblait à ceci :

class MaClasseQuelconque(quelquechose):
    # Mon code ici

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

Alors, n'hésitez pas à écrire le code qui vous convient le mieux. :)

4 votes

Un avantage d'appeler main avec sys.argv comme paramètre comme indiqué ici est que cette approche fonctionne bien avec le module argparse (qui, à mon avis, est la Bonne façon de gérer les arguments de la ligne de commande). Tout ce que vous devez faire différemment est de passer argv à parse_args dans main.

93voto

pyfunc Points 31088

Si le contenu de foo.py

imprimer __name__
if __name__ == '__main__':
    imprimer 'XXXX'

Un fichier foo.py peut être utilisé de deux façons.

  • importé dans un autre fichier : import foo

Dans ce cas, __name__ est foo, la section de code n'est pas exécutée et ne imprime pas XXXX.

  • exécuté directement : python foo.py

Lorsqu'il est exécuté directement, __name__ est le même que __main__ et le code dans cette section est exécuté et imprime XXXX

Une des utilisations de cette fonctionnalité est d'écrire différents types de tests unitaires dans le même module.

23voto

Johnsyweb Points 45395

"Que fait if __name__==“__main__”: ?" a déjà été répondu.

Avoir une main() fonction vous permet d'appeler sa fonctionnalité si vous importez le module. Le principal (sans jeu de mots) avantage de cela (à mon avis) est que vous pouvez le tester unitairement.

2 votes

2 questions ayant la même réponse ne signifie pas qu'ils sont des doublons

6 votes

@bubakazouba: Je suis d'accord. Je n'ai pas marqué cette question comme un doublon. Une partie de cette question a une très bonne réponse, je n'ai vu aucun intérêt à duplicater la réponse. J'ai répondu à le reste de la question.

8voto

Noe Points 306

Considérez le deuxième script. Si vous l'importez dans un autre, les instructions, comme au "niveau global", seront exécutées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X