Deklarieren Sie die Funktion am Ende der Datei in Python

90

Ist es möglich, eine Funktion aufzurufen, ohne sie zuvor vollständig definiert zu haben? Beim Versuch erhalte ich die Fehlermeldung: " Funktionsname ist nicht definiert". Ich komme aus einem C ++ - Hintergrund, daher macht mich dieses Problem fertig.

Deklarieren der Funktion vor dem Arbeiten:

def Kerma():
        return "energy / mass"    

print Kerma()

Der Versuch, die Funktion aufzurufen, ohne sie zuvor zu definieren, führt jedoch zu folgenden Problemen:

print Kerma()

def Kerma():
    return "energy / mass"

In C ++ können Sie eine Funktion nach dem Aufruf deklarieren, sobald Sie den Header davor platziert haben.

Vermisse ich hier etwas?

TheGentleOne
quelle
5
In Python gibt es kein "Deklarieren". Es gibt die Definition (die vollständig sein muss) oder es gibt nichts.
S.Lott
2
Sie sagen: "Es gibt Ärger". Können Sie das näher erläutern?
Martin Del Vecchio
Mögliches Duplikat der Deklarationsfunktionen in Python nach dem Aufruf
Benutzer
Für den Fall , fragt jemand:Kerma is an acronym for "kinetic energy released per unit mass"
Anon
1
Ich weiß, dass dies super alt ist, aber warum hat niemand empfohlen, die Funktionen in eine separate .pyDatei zu stellen und diese zu importieren? Gibt es einige unbeabsichtigte Konsequenzen?
Kyle

Antworten:

140

Eine Art und Weise, die in Python irgendwie idiomatisch ist, ist das Schreiben:

def main():
    print Kerma()

def Kerma():
    return "energy / mass"    

if __name__ == '__main__':
    main()

Dies ermöglicht Ihnen , Sie Code in der gewünschten Reihenfolge so lange wie zu schreiben , wie Sie die Funktion halten Aufruf mainam Ende.

Muhammad Alkarouri
quelle
4
@ Muhammad: Während dies ein praktikabler Ansatz ist, ist er in Python sicherlich nicht idiomatisch. Im Gegenteil, Sie werden feststellen, dass die meisten mainFunktionen normalerweise am Ende stehen.
Eli Bendersky
14
@ Eli Bendersky: Ich würde behaupten, dass der if __name__ == '__main__':Wechsel der gemeinsame idiomatische Teil ist.
S.Lott
2
@Eli: Der idiomatische Teil ist die if-Klausel am Ende: Kein Code auf der obersten Ebene des Moduls, dann am Ende eine Hauptfunktion aufrufen, wenn das Modul main ist .
Ned Batchelder
1
@Eli: Der idiomatische Teil ist der if ... __main__':. Ich habe nicht gesagt, dass das mainüber dem Rest des Codes platziert werden sollte. Ich sagte, der wichtige Teil ruft _\_main__am Ende an, und es spielt keine Rolle, wo Sie dann seine Definition platzieren.
Muhammad Alkarouri
2
Mit dem Schalter if name == ' main ': spielt es keine Rolle, wie Sie Ihre Funktionen bestellen. Das ist das Richtige (TM).
MKesper
18

Wenn ein Python-Modul (.py-Datei) ausgeführt wird, werden die darin enthaltenen Anweisungen der obersten Ebene in der Reihenfolge ausgeführt, in der sie angezeigt werden, von oben nach unten (von Anfang bis Ende). Dies bedeutet, dass Sie auf etwas erst verweisen können, wenn Sie es definiert haben. Zum Beispiel wird der folgende Fehler generiert:

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

Im Gegensatz zu vielen anderen Sprachen defund classAnweisungen ausführbar sind in Python-nicht nur deklarative-so dass Sie nicht verweisen können entweder aoder bbis das passiert , und sie sind definiert. Aus diesem Grund hat Ihr erstes Beispiel Probleme: Sie verweisen auf die Kerma()Funktion, bevor ihre defAnweisung ausgeführt und der Text verarbeitet wurde und das resultierende Funktionsobjekt an den Namen der Funktion gebunden ist, sodass es zu diesem Zeitpunkt im Skript nicht definiert ist.

Programme in Sprachen wie C ++ werden normalerweise vor der Ausführung vorverarbeitet. Während dieser Kompilierungsphase werden das gesamte Programm und alle #includeDateien, auf die es verweist, gleichzeitig gelesen und verarbeitet. Im Gegensatz zu Python verfügt diese Sprache über deklarative Anweisungen, mit denen der Name und die aufrufende Funktionsfolge (oder der statische Variablentyp) vor der Verwendung deklariert (aber nicht definiert) werden können, sodass der Compiler, wenn er auf seinen Namen stößt, über genügend Informationen verfügt, um deren Namen zu überprüfen Verwendung, die in erster Linie Typprüfungen und Typkonvertierungen umfasst, für die noch keine Definition des tatsächlichen Inhalts oder der Codekörper erforderlich ist.

Martineau
quelle
Es ist nicht so, dass eine dynamische Sprache das nicht kann. Perl ist eine dynamische Sprache und Sie können eine Funktion aufrufen, bevor Sie sie definieren. Das liegt daran, dass es eine Kompilierungsphase und eine Ausführungsphase gibt (obwohl seltsam, aber nützlich, können Sie festlegen, dass Code während der Kompilierungsphase ausgeführt wird). Dies funktioniert: doit(); sub doit { print("I'm doing it!\n"); }
John Deighan
10

Dies ist in Python nicht möglich, aber ehrlich gesagt werden Sie bald feststellen, dass Sie es überhaupt nicht brauchen. Die pythonische Methode zum Schreiben von Code besteht darin, Ihr Programm in Module zu unterteilen, die Klassen und Funktionen definieren, und in ein einziges "Hauptmodul", das alle anderen importiert und ausgeführt wird.

Für einfache Wegwerf-Skripte gewöhnen Sie sich daran, den "ausführbaren Teil" am Ende zu platzieren, oder lernen Sie noch besser, eine interaktive Python-Shell zu verwenden.

Eli Bendersky
quelle
1

Python ist eine dynamische Sprache und der Interpreter nimmt immer den Status der Variablen (Funktionen, ...) an, wie sie sich zum Zeitpunkt des Aufrufs befinden. Sie können die Funktionen in einigen if-Blöcken sogar neu definieren und jedes Mal anders aufrufen. Deshalb müssen Sie sie definieren, bevor Sie sie aufrufen.

Eumiro
quelle