Déclarer la fonction à la fin du fichier en Python

92

Est-il possible d'appeler une fonction sans d'abord la définir complètement? En essayant cela, j'obtiens l'erreur: " nom_fonction n'est pas défini". Je viens d'un arrière-plan C ++ donc ce problème me laisse perplexe.

Déclarer la fonction avant les travaux:

def Kerma():
        return "energy / mass"    

print Kerma()

Cependant, tenter d'appeler la fonction sans la définir au préalable pose problème:

print Kerma()

def Kerma():
    return "energy / mass"

En C ++, vous pouvez déclarer une fonction après l'appel une fois que vous placez son en-tête devant elle.

Est-ce que j'ai râté quelque chose?

TheGentleOne
la source
5
En Python, il n'y a pas de "déclarer". Il y a la définition (qui doit être complète) ou il n'y a rien.
S.Lott
2
Vous dites: "ça cause des problèmes". Pourriez-vous préciser ceci?
Martin Del Vecchio
Possible duplication des fonctions
utilisateur
Dans le cas où quelqu'un se demande:Kerma is an acronym for "kinetic energy released per unit mass"
Anon
1
Je sais que c'est très ancien, mais pourquoi personne n'a-t-il recommandé de placer les fonctions dans un .pyfichier séparé et de les importer? Y a-t-il des conséquences involontaires?
Kyle

Réponses:

144

Une façon qui est en quelque sorte idiomatique en Python est d'écrire:

def main():
    print Kerma()

def Kerma():
    return "energy / mass"    

if __name__ == '__main__':
    main()

Cela vous permet d'écrire votre code dans l'ordre que vous aimez tant que vous continuez d'appeler la fonction mainà la fin.

Muhammad Alkarouri
la source
4
@Muhammad: bien que ce soit une approche viable, ce n'est sûrement pas idiomatique en Python. Bien au contraire, vous remarquerez que la plupart des mainfonctions sont généralement placées à la fin.
Eli Bendersky
14
@Eli Bendersky: Je dirais que le if __name__ == '__main__':commutateur est la partie idiomatique commune.
S.Lott
2
@Eli: la partie idiomatique est la clause if à la fin: pas de code au niveau supérieur du module, puis à la fin invoquer une fonction main si le module est principal .
Ned Batchelder
1
@Eli: La partie idiomatique est le if ... __main__':. Je n'ai pas dit que le maindevrait être placé au-dessus du reste du code. J'ai dit que la partie importante est l'appel _\_main__à la fin, et peu importe où vous placez sa définition alors.
Muhammad Alkarouri
2
Avec le if name == ' main ': switch, la façon dont vous commandez vos fonctions n'a plus d'importance. C'est la bonne chose (TM) à faire.
MKesper
18

Lorsqu'un module Python (fichier .py) est exécuté, les instructions de niveau supérieur qu'il contient sont exécutées dans l'ordre dans lequel elles apparaissent, de haut en bas (du début à la fin). Cela signifie que vous ne pouvez pas référencer quelque chose tant que vous ne l'avez pas défini. Par exemple, ce qui suit générera l'erreur affichée:

c = a + b  # -> NameError: name 'a' is not defined
a = 13
b = 17

Contrairement à beaucoup d' autres langues, defet les classdéclarations sont exécutables en Python , et pas seulement déclaratif-vous ne pouvez pas référencer aou bjusqu'à ce que cela arrive et ils sont définis. C'est pourquoi votre premier exemple a des problèmes: vous faites référence à la Kerma()fonction avant que son definstruction ne soit exécutée et que le corps ait été traité et que l'objet fonction résultant soit lié au nom de la fonction, donc il n'est pas défini à ce stade dans le script.

Les programmes dans des langages comme C ++ sont généralement prétraités avant d'être exécutés et pendant cette étape de compilation, tout le programme et tous les #includefichiers auxquels il fait référence sont lus et traités en même temps. Contrairement à Python, ce langage propose des instructions déclaratives qui permettent de déclarer le nom et la séquence d'appel des fonctions (ou le type statique de variables) (mais non défini), avant utilisation afin que lorsque le compilateur rencontre leur nom, il dispose de suffisamment d'informations pour vérifier leur l'utilisation, qui implique principalement la vérification de type et les conversions de type, dont aucune n'exige que leur contenu réel ou leur corps de code ait encore été défini.

Martineau
la source
Ce n'est pas qu'un langage dynamique ne peut pas faire cela. Perl est un langage dynamique et vous pouvez appeler une fonction avant de la définir. C'est parce qu'il a une phase de compilation et une phase d'exécution (bien que curieusement, mais utilement, vous pouvez organiser pour exécuter du code pendant la phase de compilation). Cela fonctionne: doit(); sub doit { print("I'm doing it!\n"); }
John Deighan
10

Ce n'est pas possible en Python, mais très franchement, vous constaterez bientôt que vous n'en avez pas du tout besoin. La manière Pythonic d'écrire du code est de diviser votre programme en modules qui définissent les classes et les fonctions, et un seul "module principal" qui importe tous les autres et s'exécute.

Pour de simples scripts jetables, habituez-vous à placer la «partie exécutable» à la fin, ou mieux encore, apprenez à utiliser un shell Python interactif.

Eli Bendersky
la source
1

Python est un langage dynamique et l'interpréteur prend toujours l'état des variables (fonctions, ...) tels qu'ils sont au moment de les appeler. Vous pouvez même redéfinir les fonctions de certains blocs if et les appeler à chaque fois différemment. C'est pourquoi vous devez les définir avant de les appeler.

eumiro
la source