Celem tworzenia funkcji w programowaniu jest stworzenie kodu, który można wywołać wielokrotnie w dowolnym momencie programu i dla różnych danych. Weźmy prosty przykład obliczania średniej wszystkich liczb parzystych znajdujących się w liście. Poniższy kod pokazuje jak wykonać taką operację beż użycia funkcji:
lista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
suma_parzystych = 0
ilosc_parzystych = 0
for liczba in lista:
if liczba % 2 == 0:
suma_parzystych += liczba
ilosc_parzystych += 1
srednia_parzystych = suma_parzystych / ilosc_parzystych
Widzimy, że poza deklaracją listy potrzebujemy użycia pętli oraz instrukcji warunkowej, aby obliczyć tak zdefiniowaną średnią. Jeżeli program wymaga wielokrotnego wykonania takiej operacji stanie się to bardzo kłopotliwe. Z tego względu wykorzystuje się funkcje. Dzięki temu nie ma konieczności wielokrotnego powtarzania tego samego kodu. Wykorzystanie funkcji ma jeszcze kilka innych zalet, które omówię w tym artykule. Zacznijmy od rozwiązania powyższego problemu z wykorzystaniem funkcji.
Tworzenie funkcji w Pythonie
Przyjrzyjmy się podstawowej strukturze funkcji w języku Python, która jest przedstawiona na rysunku poniżej. Definicję funkcji zaczynamy od słowa kluczowego def
, po którym umieszczamy nazwę funkcji, następnie w nawiasach okrągłych znajdują się argumenty funkcji, czyli zmienne, które służą do wykonania operacji. Linię kończymy znakiem :
. W następnej linii od wcięcia zapisujemy ciało funkcji, czyli wszystkie operacje, które funkcja ma wykonać. Podsumowując, w tym przykładzie tworzymy funkcję srednia_parzystych
, która będzie wykonywała określone operacje na zmiennej o nazwie lista
. Funkcje zwraca zmienną wynik
.
Uzupełnijmy teraz funkcję srednia_parzystych
o kod konieczny do obliczenia pożądanej wartości. Przeanalizujmy kod poniżej:
def srednia_parzystych(lista):
suma_parzystych = 0
ilosc_parzystych = 0
for liczba in lista:
if liczba % 2 == 0:
suma_parzystych += liczba
ilosc_parzystych += 1
if ilosc_parzystych == 0:
return 0
srednia_parzystych = suma_parzystych / ilosc_parzystych
return srednia_parzystych
Zaczynając od linii 2, w funkcji tworzone są zmienne suma_parzystych
i ilosc_parzystych
. Nastpęnie przy użyciu pętli for
(linie 5-8) zmienne te są odpowiednio modyfikowane, tak aby odpowiadały wartościom zawartym w liście lista
. Funkcja obliczy i zwróci poprzez słowo kluczowe return
wartość srednia_parzystych
dla zadanej zmiennej lista
. W liniach 10-11 znajduje się instrukcja warunkowa, która zwróci wynik 0, jeśli w liście nie ma wartości parzystych. Wystąpienie słowa return
powoduje, że funkcje kończy swoje działanie. Dlatego występienie tego warunku swpoduje, że dalsze operacje (linie 13-14) nie zostaną wykonane.
Wywołanie funkcji w Pythonie
Do tej pory zdefiniowaliśmy funkcję, jednak nie wykonaliśmy obliczeń dla zdefiniowanych danych. Do tego celu trzeba wywołać funkcję. Robimy to przez podanie nazwy funkcji wraz z argumentami, jak poniżej:
moja_lista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
wynik1 = srednia_parzystych(moja_lista)
print("Średnia wartość parzystych liczb w liście:", wynik1)
W przykładzie powyżej najpierw zdefiniowaliśmy listę, po czym wywołaliśmy funkcję srednia_parzystych
, podając zmienną moja_lista
jako argument. Wynik działania funkcji jest przypisany do zmiennej wynik1
i następnie wyświetlony na konsoli.
Jak już wcześniej wspomniałem, główną zaletą funkcji jest możliwość jej wywoływania dla różnych danych. Takie rozwiązanie pokazałem w poniższym kodzie, który wykonuje obliczenia dla trzech różnych list.
lista_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print("Średnia wartość parzystych liczb w liście 1:", srednia_parzystych(lista_1))
lista_2 = [1, 3, 5, 8, 9]
print("Średnia wartość parzystych liczb w liście 2:", srednia_parzystych(lista_2))
lista_3 = [11, 13, 15, 17, 19]
print("Średnia wartość parzystych liczb w liście 3:", srednia_parzystych(lista_3))
Wynik:
Średnia wartość parzystych liczb w liście 1: 6.0
Średnia wartość parzystych liczb w liście 2: 8.0
Średnia wartość parzystych liczb w liście 3: 0
Użycie uprzednio zdefiniowanej funkcji jest proste i wygodne. Minimalizuje ilość kodu, jak również ryzyko popełnienia dodatkowych błędów. Możemy również określić jak program ma się zachować w przypadku nietypowych danych. W przedstawionym przykładzie funkcja zwraca wartość zero, gdy lista nie zawiera liczb parzystych. To rozwiązanie można modyfikować według potrzeb.
Argumenty funkcji Python
Funkcja może nie posiadać argumentów, w przypadku, gdy nie potrzebuje żadnych danych do działania. Przykładowa funkcja przedstawiona poniżej służy do wyświetlania komunikatu o dzisiejszej dacie. Jak widać po nazwie funkcji dzisiejsza_data
występują puste nawiasy okrągłe. Wywołanie funkcji w linii jedenastej odbywa się poprzez podanie nazwy funkcji z pustymi nawiasami.
from datetime import date
def dzisiejsza_data():
dzis = date.today()
return dzis.strftime("%Y-%m-%d")
# Wywołanie funkcji i wyświetlenie wyniku
dzis = dzisiejsza_data()
print(f"Dzisiejsza data to: {dzis}")
Wynik:
Dzisiejsza data to: 2024-03-04
Wywołanie funkcji musi opowiadać definicji funkcji, zatem liczba argumentów również powinna być zgodna. Jeżeli wywołamy funkcję srednia_parzystych
bez argumentów:
srednia_parzystych()
To otrzymamy komunikat o błędzie TypeError
i informację o brakującym argumencie:
TypeError Traceback (most recent call last)
Cell In[5], line 1
----> 1 srednia_parzystych()
TypeError: srednia_parzystych() missing 1 required positional argument: 'lista'
Argumenty domyślne funkcji
W Pythonie mamy możliwość ustawienia domyślnej wartości argumentu. Rozważmy poniższą funkcję stworz_zamowienie
, która jak wskazuje nazwa tworzy zamówienie na towar (przedmiot
). Widzimy, że funkcja ma dwa argumenty: przedmiot
oraz termin_realizacji
. Argument termin_realizacji
ma przypisaną wartość 7 w pierwszej linii definiującej funkcję, co oznacza, że jeżeli wywołamy funkcję bez podania tego argumentu, zostanie mu przypisana wartość domyślna.
def stworz_zamowienie(przedmiot, termin_realizacji=7):
"""
Funkcja tworzy słownik z zamówieniem.
Argumenty:
przedmiot (str): Nazwa przedmiotu zamówienia.
termin_realizacji (int): Termin realizacji zamówienia w dniach. Domyślnie 7.
Zwraca:
dict: Słownik z kluczami "przedmiot" i "termin_realizacji".
"""
zamowienie = {
"przedmiot": przedmiot,
"termin_realizacji": termin_realizacji,
}
return zamowienie
Wywołajmy teraz funkcję stworz_zamowienie
na dwa sposoby. W pierwszym podamy tylko jeden argument “Laptop”, a w drugim dwa argumenty: “Telefon” oraz liczbę 14.
# Przykład użycia funkcji stworz_zamowienie
zamowienie1 = stworz_zamowienie("Laptop")
zamowienie2 = stworz_zamowienie("Telefon", 14)
print(f"Zamówienie 1: {zamowienie1}")
print(f"Zamówienie 2: {zamowienie2}")
Wynik:
Zamówienie 1: {'przedmiot': 'Laptop', 'termin_realizacji': 7}
Zamówienie 2: {'przedmiot': 'Telefon', 'termin_realizacji': 14}
Widzimy powyżej, że przypisanie domyślnej wartości do argumentu powoduje, że możemy wywołać funkcję z jego pominięciem. Co do przydatności tego rozwiązania, to przykład powyżej dobrze to ilustruje. W sytuacjach, gdy wartość zmiennej jest “standardowa” możemy z góry ją przyjąć, a odstępstwa od reguły możemy uwzględnić poprzez podanie wartości, gdy nie jest ona domyślna.
Argumenty pozycyjne i nazwane
Argumenty do funkcji możemy przekazać do funkcji w postaci argumntów pozycyjnych lub argumentów nazwanych. Argumenty pozycyjne to wartości przekazywane do funkcji na podstawie kolejności, w jakiej parametry zostały wymienione podczas definiowania funkcji. Argumenty nazwane przekazujemy do funkcji w sposób argument=wartość
. Oba sposoby przedsawiono w poniższym przykładzie:
# Przykład użycia z argumentami pozycyjnymi
zamowienie1 = stworz_zamowienie("Ładowarka", 3)
# Przykład użycia z argumentami nazwanymi
zamowienie2 = stworz_zamowienie(termin_realizacji=7, przedmiot="Telefon")
Korzystając z argumentów pozycyjnych musimy przestrzegać kolejności, w jakiej argumenty zostały określone w definicji funkcji. Korzystając z argumentów nazwanych nie ma takiej konieczności, ponieważ jednoznacznie określamy którą wartość przypisujemy do którego argumentu.
Dowolna liczba argumentów
W Pythonie możemy przekazywać zmienną liczbę argumentów do funkcji za pomocą specjalnych argumentów:
- *args (argumenty pozycyjne)
- **kwargs (argumenty nazwane)
Poniższy przykład pokazuje jak przekazać zmienną liczbę argumentów pozycyjnych przy użyciu *args
.
def add(*liczby):
total = 0
for num in liczby:
total += num
return total
print(add(2, 3))
print(add(2, 3, 5))
print(add(2, 3, 5, 7))
print(add(2, 3, 5, 7, 9))
Wynik:
5
10
17
26
Przykład poniżej pokazuje jak użyć **kwargs
. Argumenty są przekazywane w postaci słownika, przez który możemy iterować.
def witaj(**kwargs):
for klucz, wartosc in kwargs.items():
print(f"{klucz}: {wartosc}")
witaj(imie='Jan', nazwisko='Kowalski', wiek='33')
witaj(imie='Mateusz', nazwisko='Witkowski')
Wynik:
imie: Jan
nazwisko: Kowalski
wiek: 33
imie: Mateusz
nazwisko: Witkowski
Polimorfizm funkcji
Słowo „polimorfizm” oznacza „wiele form”, a w programowaniu odnosi się do metod, funkcji i operatorów o tej samej nazwie, które można wykonać na zmiennych różnych typów. Przykładem funkcji polimorficznej jest funkcja len()
, która jak wiemy działa m. in. na listach, stringach czy słownikach.
Funkcja lambda
Funkcja lambda to funkcja anonimowa, czyli niezwiązana z konkretną nazwą do identyfikacji. W języku Python określana jest przez jedno wyrażenie i wykorzystywana jest między innymi w takich zadaniach jak filtrowanie.
Składnia funkcji lambda jest następująca:
lambda argumenty: wyrażenie
Przykładem prostej funkcji lambda jest funkcja, która dodaje liczbę 5 do podanej jako argument zmiennej:
x = lambda a: a + 5
print(x(5))
Powyższą funkcję interpretujemy w następujący sposób: a
to argument funkcji, która oblicza wyrażenie a + 5
.
Funkcja lambda może przyjmować więcej niż jeden argument. Funkcja zdefiniowana w poniższym przykładzie oblicza potęgę a ** b
.
x = lambda a, b : a ** b
print(x(5, 6))
Filtrowanie z użyciem funkcji lambda
Bardzo przydatne jest stosowanie funkcji lambda wewnątrz innej funkcji. Jednym z przykładów jest filtrowanie. Rozważmy następujący kod:
lista = [15, 22, 53, 68, 201]
lista_filtrowana = list(filter(lambda x: (x % 2 == 0), lista))
print(lista_filtrowana)
Wynik:
[22, 68]
Funkcja filter()
przyjmuje dwa argumenty: funkcję anonimową lambda oraz listę. Funkcja lambda określa warunek filtrowania – w tym przykładzie sprawdza ona czy argument x
jest liczbą parzystą. Wynik działania funkcji filter()
jest konwertowany do listy poprzez użycie funkcji list()
.