Czy można zadeklarować dalej funkcję w Pythonie? Chcę posortować listę za pomocą własnej cmp
funkcji, zanim zostanie zadeklarowana.
print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])
Zorganizowałem swój kod, aby wstawić definicję cmp_configs
metody po wywołaniu. Błąd tego błędu:
NameError: name 'cmp_configs' is not defined
Czy jest jakiś sposób na „zadeklarowanie” cmp_configs
metody przed jej użyciem? Czy dzięki temu mój kod będzie wyglądał na czystszy?
Zakładam, że niektórzy ludzie będą mieli ochotę powiedzieć mi, że powinienem po prostu zreorganizować swój kod, aby nie miałem tego problemu. Są jednak przypadki, w których jest to prawdopodobnie nieuniknione, na przykład przy wdrażaniu niektórych form rekurencji. Jeśli nie podoba ci się ten przykład, załóż, że mam przypadek, w którym naprawdę konieczne jest przekazanie dalej zadeklarowanej funkcji.
Rozważ ten przypadek, w którym w Pythonie konieczne byłoby przekazywanie funkcji do przodu:
def spam():
if end_condition():
return end_result()
else:
return eggs()
def eggs():
if end_condition():
return end_result()
else:
return spam()
Gdzie end_condition
i end_result
zostały wcześniej zdefiniowane.
Czy jedynym rozwiązaniem jest reorganizacja kodu i zawsze umieszczanie definicji przed wywołaniami?
źródło
main()
?import your_module
Co możesz zrobić, to owinąć wywołanie we własną funkcję.
Po to aby
pęknie, ale
będzie działać poprawnie.
Ogólna zasada nie
Python
polega na tym, że funkcja powinna być zdefiniowana wyżej w kodzie (jak w ), ale że należy ją zdefiniować przed użyciem.Pascal
Mam nadzieję, że to pomaga.
źródło
if __name__=="__main__":
rozwiązanie działa.Jeśli uruchomisz skrypt w następujący sposób:
wtedy prawdopodobnie nie musisz się martwić takimi sprawami jak „deklaracja przekazania”. Widzisz, interpreter ładuje wszystkie twoje funkcje, a następnie uruchamia twoją funkcję main (). Oczywiście upewnij się, że wszystkie importy również są poprawne ;-)
Pomyśl o tym, nigdy nie słyszałem czegoś takiego jak „deklaracja przekazania” w pythonie ... ale z drugiej strony, mogę się mylić ;-)
źródło
Jeśli wywołanie cmp_configs mieści się w jego własnej definicji funkcji, wszystko powinno być w porządku. Dam przykład.
Zasadniczo umieszczenie kodu w funkcjach (takich jak main ()) rozwiąże problem; wystarczy wywołać main () na końcu pliku.
źródło
Przepraszam za ożywienie tego wątku, ale nie była tutaj omawiana strategia, która może mieć zastosowanie.
Za pomocą refleksji można zrobić coś podobnego do przekazania deklaracji. Załóżmy na przykład, że masz sekcję kodu, która wygląda następująco:
W ten sposób ustaliliśmy, jaką funkcję chcemy wywołać, zanim zostanie ona faktycznie zdefiniowana, w efekcie deklaracja przekazania. W python oświadczenie
globals()[function_name]()
jest taka sama, jakfoo()
gdybyfunction_name = 'foo'
z powodów omówionych powyżej, ponieważ Python musi odnośnika każdą funkcję przed nazywając ją. Gdyby użyćtimeit
modułu, aby zobaczyć porównanie tych dwóch instrukcji, mają one dokładnie taki sam koszt obliczeniowy.Oczywiście przykład tutaj jest bardzo bezużyteczny, ale jeśli ktoś miałby mieć złożoną strukturę, która wymagałaby wykonania funkcji, ale musiałaby zostać zadeklarowana wcześniej (lub strukturalnie nie ma sensu mieć jej później), można po prostu zapisać ciąg znaków i spróbuj wywołać tę funkcję później.
źródło
W pythonie nie ma czegoś takiego jak deklaracja przesyłania dalej. Musisz tylko upewnić się, że twoja funkcja jest zadeklarowana, zanim będzie potrzebna. Zauważ, że treść funkcji nie jest interpretowana, dopóki funkcja nie zostanie wykonana.
Rozważ następujący przykład:
Możesz pomyśleć, że ciało funkcji jest tylko kolejnym skryptem, który zostanie zinterpretowany po wywołaniu funkcji.
źródło
Nie, nie sądzę, aby w Pythonie można było zadeklarować dalej funkcję.
Wyobraź sobie, że jesteś interpretatorem języka Python. Kiedy dojdziesz do linii
albo wiesz, co to jest cmp_configs, albo nie. Aby kontynuować, musisz znać cmp_configs. Nie ma znaczenia, czy nastąpi rekurencja.
źródło
Czasami algorytm jest najłatwiejszy do zrozumienia z góry na dół, zaczynając od ogólnej struktury i przechodząc do szczegółów.
Możesz to zrobić bez deklaracji przesyłania dalej:
źródło
Wynik:
źródło
Nie można zadeklarować do przodu funkcji w Pythonie. Jeśli masz logikę wykonywaną przed zdefiniowaniem funkcji, prawdopodobnie i tak masz problem. Umieść swoją akcję
if __name__ == '__main__'
na końcu skryptu (wykonując funkcję, którą nazwiesz „main”, jeśli nie jest trywialna), a twój kod będzie bardziej modułowy i będziesz mógł użyć go jako modułu, jeśli kiedykolwiek będziesz potrzebować do.Zastąp też tę listę zrozumieniem generatora ekspresowego (tj.
print "\n".join(str(bla) for bla in sorted(mylist, cmp=cmp_configs))
)Nie używaj również
cmp
, co jest przestarzałe. Użyjkey
i podaj mniej niż funkcję.źródło
Zaimportuj sam plik. Zakładając, że plik nazywa się test.py:
źródło
„po prostu zreorganizuj mój kod, aby nie miałem tego problemu”. Poprawny. Proste do zrobienia. Zawsze działa.
Zawsze możesz podać funkcję przed jej odwołaniem.
„Są jednak przypadki, w których jest to prawdopodobnie nieuniknione, na przykład podczas wdrażania niektórych form rekurencji”
Nie widzę, jak to jest nawet możliwe. Podaj przykład miejsca, w którym nie można zdefiniować funkcji przed jej użyciem.
źródło
Teraz poczekaj chwilę. Kiedy Twój moduł osiągnie instrukcję print w twoim przykładzie, zanim
cmp_configs
został zdefiniowany, czego dokładnie oczekujesz?Jeśli Twoje pytanie za pomocą print naprawdę próbuje przedstawić coś takiego:
wtedy nie ma wymogu zdefiniowania
cmp_configs
przed wykonaniem tej instrukcji, wystarczy zdefiniować ją później w kodzie i wszystko będzie dobrze.Teraz, jeśli próbujesz odwołać się
cmp_configs
do domyślnej wartości argumentu do lambda, to jest inna historia:Teraz potrzebujesz
cmp_configs
zdefiniowanej zmiennej, zanim dojdziesz do tej linii.[EDYCJA - ta kolejna część okazuje się niepoprawna, ponieważ domyślna wartość argumentu zostanie przypisana podczas kompilacji funkcji, a ta wartość zostanie wykorzystana, nawet jeśli później zmienisz wartość cmp_configs.]
Na szczęście Python, który jest tak dostosowany do typów, nie przejmuje się tym , co definiujesz jako
cmp_configs
, więc możesz po prostu przedłożyć to zdanie:A kompilator będzie szczęśliwy. Pamiętaj tylko, aby zadeklarować prawdziwe,
cmp_configs
zanim zaczniesz wzywaćfn
.źródło
Jednym ze sposobów jest utworzenie funkcji modułu obsługi. Zdefiniuj moduł obsługi na wczesnym etapie i umieść moduł obsługi pod wszystkimi metodami, które musisz wywołać.
Następnie po wywołaniu metody modułu obsługi w celu wywołania funkcji będą one zawsze dostępne.
Przewodnik może wziąć argument
nameOfMethodToCall
. Następnie używa zestawu instrukcji if do wywołania właściwej metody.To rozwiązałoby problem.
źródło
Tak, możemy to sprawdzić.
Wejście
Wynik
Jak wspomniano powyżej BJ Homer, ogólną zasadą w Pythonie nie jest to, że funkcja powinna być zdefiniowana wyżej w kodzie (jak w Pascalu), ale że należy ją zdefiniować przed użyciem.
Mam nadzieję, że to pomaga.
źródło
print_lyrics()
wywoływany (używany) w wierszu 1, zanim zostanie zdefiniowany? Skopiowałem ten fragment kodu i próbowałem go uruchomić, co powoduje błądNameError: name 'print_lyrics' is not defined
w wierszu 1. Czy możesz to wyjaśnić?