Zadeklaruj funkcję na końcu pliku w Pythonie

94

Czy można wywołać funkcję bez wcześniejszego jej pełnego zdefiniowania? Przy próbie tego pojawia się błąd: „ nazwa_funkcji nie jest zdefiniowana”. Pochodzę z C ++, więc ten problem mnie przytłacza.

Deklarowanie funkcji przed działaniem:

def Kerma():
        return "energy / mass"    

print Kerma()

Jednak próba wywołania funkcji bez wcześniejszego jej zdefiniowania sprawia kłopoty:

print Kerma()

def Kerma():
    return "energy / mass"

W C ++ możesz zadeklarować funkcję po wywołaniu, gdy umieścisz przed nią jej nagłówek.

Czy coś mi umyka?

TheGentleOne
źródło
5
W Pythonie nie ma „deklaracji”. Jest definicja (która musi być kompletna) albo nie ma nic.
S.Lott,
2
Mówisz: „to sprawia kłopoty”. Czy możesz to rozwinąć?
Martin Del Vecchio,
Możliwy duplikat funkcji Declaration w Pythonie po wywołaniu
użytkownik
Na wypadek gdyby ktoś się zastanawiał:Kerma is an acronym for "kinetic energy released per unit mass"
anon
1
Wiem, że to jest bardzo stare, ale dlaczego nikt nie zaleca umieszczania funkcji w oddzielnym .pypliku i importowania tego? Czy są jakieś niezamierzone konsekwencje?
Kyle,

Odpowiedzi:

145

Jednym ze sposobów, które jest trochę idiomatyczne w Pythonie, jest pisanie:

def main():
    print Kerma()

def Kerma():
    return "energy / mass"    

if __name__ == '__main__':
    main()

Pozwala to na pisanie kodu w dowolnej kolejności, o ile wywołujesz funkcję mainna końcu.

Muhammad Alkarouri
źródło
4
@Muhammad: chociaż jest to realne podejście, z pewnością nie jest idiomatyczne w Pythonie. Wręcz przeciwnie, zauważysz, że większość mainfunkcji jest zwykle umieszczona na końcu.
Eli Bendersky,
14
@Eli Bendersky: Powiedziałbym, że if __name__ == '__main__':przełącznik jest wspólną częścią idiomatyczną.
S.Lott,
2
@Eli: część idiomatyczna to klauzula if na końcu: brak kodu na najwyższym poziomie modułu, na końcu wywołaj funkcję główną, jeśli moduł jest main .
Ned Batchelder
1
@Eli: Część idiomatyczna to if ... __main__':. Nie powiedziałem, że mainpowinien być umieszczony nad resztą kodu. Powiedziałem, że ważna część to wezwanie _\_main__na końcu i nie ma znaczenia, gdzie wtedy umieścisz jego definicję.
Muhammad Alkarouri
2
W przypadku przełącznika if name == ' main ': nie ma znaczenia, w jaki sposób zamawiasz funkcje. To jest właściwa rzecz (TM) do zrobienia.
MKesper
18

Kiedy uruchamiany jest moduł Pythona (plik .py), zawarte w nim instrukcje najwyższego poziomu są wykonywane w kolejności, w jakiej się pojawiają, od góry do dołu (od początku do końca). Oznacza to, że nie możesz się do czegoś odwołać, dopóki tego nie zdefiniujesz. Na przykład poniższe wygeneruje pokazany błąd:

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

W przeciwieństwie do wielu innych językach, defa classsprawozdania są wykonywalne w Pythonie nie tylko deklaratywne, więc nie można odwołać albo aczy baż tak się dzieje i są one zdefiniowane. Z tego powodu pierwszy przykład ma problem - odwołujesz się do Kerma()funkcji przed wykonaniem jej definstrukcji i przetworzeniem treści, a wynikowy obiekt funkcji jest powiązany z nazwą funkcji, więc nie jest zdefiniowany w tym momencie w skrypcie.

Programy w językach takich jak C ++ są zwykle wstępnie przetwarzane przed uruchomieniem, a na tym etapie kompilacji cały program i wszystkie #includepliki, do których się odnosi, są odczytywane i przetwarzane jednocześnie. W przeciwieństwie do Pythona, język ten zawiera deklaratywne instrukcje, które pozwalają na zadeklarowanie (ale niezdefiniowanie) nazwy i sekwencji wywoływania funkcji (lub statycznego typu zmiennych) przed użyciem, aby kompilator napotkał ich nazwę miał wystarczająco dużo informacji, aby sprawdzić ich użycie, które obejmuje przede wszystkim sprawdzanie typów i konwersje typów, z których żadna nie wymaga jeszcze zdefiniowania ich rzeczywistej zawartości ani treści kodu.

martineau
źródło
Nie jest tak, że dynamiczny język tego nie potrafi. Perl jest językiem dynamicznym i możesz wywołać funkcję przed jej zdefiniowaniem. Dzieje się tak, ponieważ ma fazę kompilacji i fazę wykonywania (choć dziwnie, ale użytecznie, możesz zorganizować wykonanie kodu podczas fazy kompilacji). To działa: doit(); sub doit { print("I'm doing it!\n"); }
John Deighan
9

Nie jest to możliwe w Pythonie, ale szczerze mówiąc, wkrótce okaże się, że w ogóle go nie potrzebujesz. Pythonowym sposobem pisania kodu jest podzielenie programu na moduły, które definiują klasy i funkcje oraz jeden „główny moduł”, który importuje wszystkie pozostałe i działa.

W przypadku prostych skryptów do wyrzucenia przyzwyczaić się do umieszczania „wykonywalnej części” na końcu lub jeszcze lepiej, naucz się korzystać z interaktywnej powłoki Pythona.

Eli Bendersky
źródło
1

Python jest językiem dynamicznym, a interpreter zawsze przyjmuje stan zmiennych (funkcji, ...) taki, jaki jest w momencie ich wywołania. Możesz nawet przedefiniować funkcje w niektórych blokach if i wywoływać je za każdym razem inaczej. Dlatego musisz je zdefiniować, zanim do nich zadzwonisz.

eumiro
źródło
1

Jeśli chcesz być jak C ++ i używać wszystkiego wewnątrz funkcji. możesz wywołać pierwszą funkcję od dołu pliku, na przykład:

def main():
    print("I'm in main")
    #calling a although it is in the bottom
    a()

def b():
   print("I'm in b")

def a():
   print("I'm in a")
   b()

main()

W ten sposób Python najpierw „czyta” cały plik, a dopiero potem zaczyna wykonywanie

arye
źródło