Zapisz jako PDF

Transkrypt

Zapisz jako PDF
Funkcje
Gdy raz wymyślimy jakiś sprytny algorytm, to nie ma co go za każdym razem odkrywać na nowo.
Żeby było łatwiej pisać raz, a korzystać wielokrotnie - wymyślono funkcje.
Definiowanie funkcji
def funkcja(x, y):
BLOK INSTRUKCJI
Definicja funkcji to instrukcja złożona, podobna w strukturze do tych, które już znamy instrukcji warunkowej i pętli.
Wykonanie definicji funkcji nie wiąże się z natychmiastowym wykonaniem zawartego w niej
bloku.
W definicji funkcji (przykładowej) x i y to parametry formalne; nie mają one w tym momencie
określonych wartości, są miejscami do wypełnienia konkretnymi wartościami, gdy funkcję
postanowimy użyć.
Wykonanie definicji funkcji polega na nadaniu znaczenia jej nazwie, która odtąd będzie
oznaczała ciąg instrukcji stanowiących wewnętrzny blok.
Użycie czyli wywołanie funkcji to wyrażenie postaci
funkcja(x, y)
gdzie x i y mają już konkretne wartości (w tym miejscu mogą stać również wyrażenia złożone), które
będą użyte w instrukcjach stanowiących definicję.
W definicji na ogół występuje (raz lub więcej razy) słowo (instrukcja) return. Oznacza ono, że
w tym miejscu wykonanie funkcji się kończy - funkcja powraca. Wartość wyrażenia po słowie
return stanowi wynik zwracany przez funkcję - czyli wartość wyrażenia, będącego
wywołaniem funkcji.
Jeśli return nie ma, albo nie ma po nim wartości zwracanej, albo wykonanie funkcji kończy
się ,,wypadnięciem" przez koniec bloku, wartością zwracaną jest None - która w zasadzie do
niczego się specjalnie nie nadaje.
funkcja w Pythonie (i większości języków programowania) to coś nieco podobnego do funkcji w
matematyce, ale to nie jest to samo pojęcie:
w Pythonie wywołanie funkcji może mieć skutki uboczne;
wynik funkcji, w tym skutki uboczne, może zależeć nie tylko od argumentów wywołania.
Skutkami ubocznymi wywołania nazywamy jakiekolwiek efekty tej instrukcji, które nie sprowadzają
się do wartości zwracanej. A więc, zmianę wartości innych zmiennych, czy np. wysłanie jakichś
danych siecią, lub wypisanie czegoś na ekran.
Funkcja może być wartością zmiennej; inaczej mówiąc, funkcja może być znana pod
dodatkowymi nazwami (aliasami), może być włożona do listy na którąś z jej pozycji itp.
ff = funkcja
...
wynik = ff(x)
,,Oryginalna" nazwa funkcji, czyli występująca w jej definicji, jest jednak w pewnym sensie
uprzywilejowana.
Zmienne (nazwy) powołane do życia wewnątrz funkcji są lokalne; ich wartości ,,żyją" tylko
póki wykonuje się funkcja.
Zmienne lokalne powielające nazwy ,,zewnętrzne" względem funkcji przesłaniają te
zewnętrzne. Chyba, że użyjemy deklaracji global:
x = 1
def podwojx(): # to nie zadziała:
x = x * 2
podwojx()
UnboundLocalError
Traceback (most recent call last)
<ipython-input-3-6edd575e5cda> in <module>()
----> 1 podwojx()
<ipython-input-1-1da635f42ffa> in podwojx()
1 def podwojx():
----> 2
x *= 2
3
UnboundLocalError: local variable 'x' referenced before assignment
Jak widzimy, komunikat o błędzie pojawił się dopiero w wyniku wywołania błędnej funkcji.
x = 1
def podwojx():
global x
x = x * 2
podwojx()
print x
→ 2
# to zadziała - co nie znaczy, że jest mądre...
Należy unikać takich sztuczek, jak powyżej; jeśli już, to:
def podwoj(x):
return 2 * x
liczba = 1
print podwoj(liczba)
→ 2
Wskazówka: każde użycie deklaracji global w programie powinno być dobrze uzasadnione. Jeżeli
używamy jej więcej niż sporadycznie, to coś jest nie tak.
Funkcja może być
jednoargumentowa (jak powyższa podwoj),
dwuargumentowa (jak przykładowa),
trzy-, cztero-, ... itd.
o zmiennej liczbie argumentów, z wartościami domyślnymi dla brakujących:
def dodaj(x, y=1):
return x + y
dodaj(2, 3)
→ 5
dodaj(2)
→ 3
Ćwiczenia
1. Napisz funkcję pierwiastki(a, b, c), która wypisuje na ekran (za pomocą wywołania print)
pierwiastki równania kwadratowego o wspołczynnikach a, b i c: a * x**2 + b * x + c == 0. W
przypadku, gdy pierwiastków nie ma, wypisuje komunikat Równanie nie ma pierwiastków. W
przypadku, gdy a=0, wypisuje komunikat Błędne dane: a==0 i kończy działanie.
2. Napisz analogiczną funkcję, która zamiast bezpośrednio wypisywać rozwiązania, zwraca je jako
wynik swojego działania. Wypisaniem ich na ekran zajmuje się odrębna instrukcja. W przypadku, gdy
pierwiastków nie ma, zwraca wartość None. Nie sprawdzaj warunku a!=0 - co się dzieje, gdy nie jest
spełniony przez argumenty wywołania funkcji?
3. Napisz funkcję silnia(n), która oblicza i zwraca wartość silni: n! := 1 * 2 * 3 * ... (n
- 1) * n. Uwzględnij, że przyjmuje się że 0! = 1, natomiast dla liczb ujemnych silnia nie jest
określona - co można zasygnalizować zwracając jako wynik None. Użyj pętli for i funkcji range.
4. Funkcję silnia można zdefiniować w sposób rekurencyjny - za pomocą następujących warunków:
n! == None dla n < 0
0! == 1
n! == n * (n - 1)!
Napisz kod funkcji silnia(n) realizujący powyższą definicję. Porównaj działanie tego kodu z
realizacją tej funkcji z poprzedniego przykładu dla dużych wartości n.
poprzednie | strona główna | dalej
RobertJB (dyskusja) 16:10, 30 cze 2016 (CEST)