Wreszcie przyszedł czas na materiał z nauki Pythona, który przedstawia kolejną z podstawowych programistycznych konstrukcji 🔥! Pokażę Ci w nim czym jest, jak wygląda i co nam daje funkcja w języku Python 🤩. Dowiedz się jak skutecznie stosować słowo kluczowe "def" do definiowania własnych funkcji oraz na czym polega ich wywoływanie ❤️. Jak zainteresowany(-a), to zapraszam do środeczka 😄!

WYJAŚNIAM CZYM JEST FUNKCJA W JĘZYKU PYTHON!

Zaznajomię Cię na początku z samym terminem, potem wyjaśnię to zagadnienie teoretycznie, aż wreszcie przejdziemy do samego kodu źródłowego 🚀!

CZYM JEST FUNKCJA W JĘZYKU PYTHON?

Funkcją w Pythonie nazywamy podprogram wykonujący określone instrukcje, który może przyjmować pewne parametry i zwracać na wyjściu jakąś wartość ℹ️. Hasłem kluczowym jest tutaj "podprogram" 💥. Jest to najważniejsze hasło, abyś sobie zapamiętał(a)!

Gdy piszesz kod w skrypcie, to piszesz program 😉. Gdy piszesz kod w funkcji, to piszesz podprogram. I tak należy na to patrzeć 👀! Jest to nic innego, jak odrębny blok kodu instrukcji opatrzony nazwą do odwoływania się w dalszej części skryptu 💡.

Weźmy prosty przykład z życia: mycie zębów 😊. Mycie zębów polega na wykonaniu kilku kroków 👇:

  1. wejście do toalety,
  2. przygotowanie szczoteczki do zębów,
  3. nałożenie pasty do zębów na szczoteczkę,
  4. szorowanie zębów szczoteczką wewnątrz całej jamy ustnej,
  5. wypłukanie ust,
  6. umycie szczoteczki,
  7. odłożenie szczoteczki,
  8. wyjście z toalety.

Gdybyśmy pisali taki kod, to idealnie pasowałoby wstawienie go do funkcji ✅. Zauważ, że mycie zębów jest takim "podprogramem" w naszym życiu, bo ma swoją nazwę ("umyj zęby" 😁), wykonujemy go każdego dnia i żadna z jego czynności nigdy się nie zmieni. To stwarza perfekcyjne warunki dla funkcji i to jest ich główne zastosowanie ❤️!

W JAKIM CELU TWORZY SIĘ FUNKCJE W JĘZYKU PYTHON?

Funkcje w Pythonie stosuje się do dwóch celów 👇:

  1. wydzielenie kodu źródłowego na mniejsze "porcje",
  2. możliwość wielokrotnego wykonania tego samego kodu.

Dwa duże plusy ➕. Po pierwsze, funkcje sprzyjają organizacji, bo właściwe instrukcje znajdują się we właściwym miejscu (wiemy gdzie ich szukać w razie chęci modyfikacji) 👍, a po drugie, nie musimy pisać tego samego N razy, gdy kiedykolwiek zajdzie potrzeba wykonania tych samych instrukcji (po prostu sięgamy do tej funkcji i ją "uruchamiamy") 👍.

Nie powinno zatem dziwić stwierdzenie, iż umiejętność tworzenia własnych funkcji jest niezbędna, aby być w stanie pisać bardziej złożone programy 🙂.

To by było tyle z teorii, więc czas na naukę kodu źródłowego 🧠! Część związana z poznawaniem funkcji od strony kodu, dzieli się na 2 etapy 👇:

  1. tworzenie (definicja),
  2. uruchamianie (poprawnie określamy to "wywoływaniem" ℹ️).

Dlatego też najpierw pokażę jak tworzymy funkcje, a potem jak się je wywołuje 🙂.

JAK STWORZYĆ FUNKCJĘ W JĘZYKU PYTHON?

Wzór na funkcję w Pythonie wygląda następująco 👇:

def [nazwa funkcji]([parametry]):
	[instrukcje]

Jak zwykle weźmy sobie całą postać pod lupę 🔍!

Postać każdej funkcji w języku Python wymaga wstawienia następujących elementów składni 👇:

  1. słowo kluczowe "def",
  2. nazwa funkcji, po której będziemy mogli ją identyfikować w dalszej części kodu (dalej wyjaśniam zasady i zalecenia ze swej strony ℹ️),
  3. para nawiasów okrągłych (musi obowiązkowo znaleźć się w zapisie, a wewnątrz nich opcjonalnie już parametry, jakie funkcja ma przyjmować),
  4. znak dwukropka (obowiązkowa rzecz, bez której będzie błąd składniowy 🚫),
  5. instrukcje po zrobieniu obowiązkowego wcięcia (poprzez spację lub tabulator), które mają się wykonać w momencie wywołania funkcji.

A teraz przybliżę dokładniej każdy z punktów 🧐.

Obojętnie czy funkcja ma cokolwiek zwracać, czy nie, zawsze piszemy to samo hasło: "def" 📝 Zaraz po nim wpisujemy nazwę dla naszej funkcji. Są pewne reguły, do których trzeba się stosować, jak również zalecenia zgodne z przyjętymi dobrymi praktykami, więc w dalszej części artykułu dokładnie je przedstawię 👌.

Po wprowadzeniu nazwy funkcji, koniecznie wstawiamy parę nawiasów okrągłych jako oznaczenie, że to ma być interpretowane jak funkcja - to także jest obowiązkowy element składni, bez którego Python odmówi wykonania programu ⛔. Wewnątrz nich umieszczamy parametry, jakie funkcja ma przyjmować w momencie wywoływania (więcej o parametrach piszę w dalszym ciągu artykułu ℹ️). Mogą one występować, lecz nie muszą 😉.

Kiedy przejdziemy przez część związaną z parametrami w nawiasie okrągłym, na samym końcu wstawiamy koniecznie dwukropek jako znak definiowania bloku instrukcji dla funkcji 💥! I to jest wszystko w tym wierszu ✔️. Od następnego robimy sobie obowiązkowe wcięcie (spacją bądź tabulatorem) i w tym miejscu piszemy instrukcje jakie się wykonają w momencie wywołania tej funkcji. Czyli one nie wykonają się natychmiastowo, zgodnie z tradycyjnym przebiegiem ⚠️. Później wyjaśnię na czym polega wywoływanie funkcji, także spokojnie 🙂.

Funkcja bez parametrów niezwracająca żadnej wartości w języku Python

Funkcja w języku Python to podprogram wykonujący określone instrukcje, który może przyjmować parametry i zwracać na wyjściu wartość określonego typu.

To jest ogólna postać każdej funkcji w Pythonie, a teraz przyjrzymy się dodatkowym elementom, które mogą zostać do niej dodane 👀! Na początek, parametry funkcji 😲!

CZYM JEST PARAMETR FUNKCJI W JĘZYKU PYTHON?

Parametr funkcji jest niczym innym, jak zmienną występującą tylko w jej w obrębie 💡. Służy do późniejszego podstawiania różnych wartości w momencie wywoływania funkcji, które z kolei trafiają do instrukcji jakie mają zostać wykonane ☑️. Parametr dodajemy poprzez wpisanie samej nazwy zmiennej, co odbiega od dominującego zapisu w wielu innych językach, w których przy każdym parametrze trzeba jeszcze dodać typ danych (wynika to z dynamicznej typizacji Pythona, którą wyjaśniłem w artykule o zmiennych ℹ️) ⚠️.

Z tego względu, ponieważ Python nie wymaga ścisłego określania typu danych parametru, to może być w rzeczywistości wszystko i nic: od liczby całkowitej (bez ułamka) do obiektu klasy 😱! Możemy coś nazwać "liczbą", a obsługa będzie dostosowania pod łańcuch znaków 💥.

Mało tego, Python nie sprawdza czy w każdym wywołaniu funkcji wstawimy poprawne typy danych w miejsca oczekiwanych parametrów 😨! Może być na przykład sytuacja, w której funkcja oczekuje łańcucha znaków, a my podaliśmy liczbę zmiennoprzecinkową (z ułamkiem) i ten kod uruchomi się bez przeciwwskazań (choć naturalnie przyniesie to późniejsze problemy) 😳.

Także w tym języku musisz mieć się na baczności czy wszystko jest zapięte na ostatni guzik, zarówno po stronie definicji funkcji, jak i wszystkich jej wywołań 💥! Przy wywołaniach upewnij się, że wszystkie parametry są właściwych typów i ich liczba zgadza się z liczbą oczekiwanych parametrów, a w definicji powinno się dodatkowo wprowadzać zabezpieczenia weryfikujące typ danych, zanim zaczniemy w ogóle cokolwiek robić na parametrach w ramach dobrej praktyki.

Natomiast na początku swojej nauki możesz pominąć to zagadnienie, aby nie obciążać się zbyt dużą ilością nowych informacji 😉. Ja tylko piszę, że trzeba być świadomym tego, że Python sporo "odpuszcza" w sprawie zachowania zgodności parametrów po stronie oczekiwanych i faktycznych ⚠️.

Tyle tytułem wstępu do parametrów, a teraz zobaczmy sobie parę przykładów funkcji przyjmujących parametr!

JAK UTWORZYĆ FUNKCJĘ Z PARAMETREM W JĘZYKU PYTHON?

Celem utworzenia funkcji z parametrem (lub wieloma parametrami), należy je po prostu wprowadzić w miejsce nawiasów okrągłych 😊. To jest przykład funkcji z jednym parametrem 👇:

def do_something(x):

Tutaj parametrem jest "x" 👀. Znajduje się wewnątrz nawiasów okrągłych. Możemy go podstawić do dowolnej instrukcji oraz wykonywać na nich odpowiednie operacje (o ile są zgodne z typem danych ⚠️), czyli robić wszystko to, co robiłeś(-aś) do tej pory na zmiennych "na zewnątrz" ❤️!

A to funkcja przyjmująca 2 parametry 👇:

def do_something(x, y):

W tym przypadku parametrami funkcji są: "x" i "y" 💕. Zobacz, że są od siebie oddzielone przecinkiem i właśnie taka obowiązuje zasada definiowania parametrów funkcji w Pythonie 🚀! Jeżeli chcesz do funkcji dodać co najmniej 2 parametry, to podajesz nazwę pierwszego parametru, potem stawiasz przecinek i podajesz nazwę kolejnego ⏩. "Simple as that" 😁!

Funkcja z jednym parametrem niezwracająca żadnej wartości w języku Python

Funkcja może przyjmować parametry, które następnie są użyte do jej instrukcji.

Chciałbym pokazać Ci jeszcze jeden przykład, który może kiedyś Ci się przewinąć 👀. To jest rzadko spotykany zapis, jednak warto go poznać 👇:

def do_something(*args):

Taki parametr z asteryskiem przed nazwą (*) oznacza tzw. "zmienną liczbę parametrów" zwaną charakterystycznie "varargs" 😮! Oznacza to, że taka funkcja przyjmuje dowolną liczbę parametrów 🔥. Możesz podczas wywołania dodać jeden, 3, 10 albo zero parametrów i żaden z tych przypadków nie zostanie potraktowany jako błąd ✅!

Funkcje ze zmienną liczbą parametrów przydają się w sytuacjach, gdy chcemy przeprowadzić jakąś operację na danych różnych wielkości. Sumowanie liczb jest świetnym przykładem, gdyż do tego możemy wstawić tyle liczb, ile chcemy (nawet zero 🙂) i dla każdego przypadku suma zostanie prawidłowo wyznaczona 👍.

To by było na tyle z podstawowych informacji o parametrach funkcji ✔️. To teraz drugi wątek - zwracanie wartości przez funkcję ↩️!

JAK UTWORZYĆ FUNKCJĘ ZWRACAJĄCĄ WARTOŚĆ W JĘZYKU PYTHON?

Aby narzucić funkcji zwracanie wartości określonego typunależy dodać słowo kluczowe "return" i podać wyrażenie jakie ma zostać zwrócone na wyjściu 💡. Oto prosty przykład zwracania kwadratu podanej w parametrze liczby 👇:

def get_square_of(n):
	return n*n

To sprawi, że funkcja przyjmie liczbę n, obliczy jej kwadrat i zwróci go na wyjściu ↩️. Instrukcja "return" powoduje natychmiastowe zakończenie wykonywania instrukcji w funkcji, dodatkowo zwracając w tym przypadku wyrażenie, choć można go też użyć do funkcji niezwracających żadnych wartości, aby zakończyć działanie wcześniej, zanim dojdziemy do ostatniej instrukcji (wtedy nie piszemy żadnego wyrażenia, tylko samo słowo "return") 👍.

Jeżeli przepływ kodu jest jedyny (nie ma instrukcji warunkowych), to instrukcja "return" zawsze pojawia się tylko jeden raz i znajduje się na samym końcu bloku kodu jako ostatnia instrukcja, aczkolwiek gdy mamy do czynienia z rozgałęzieniami powstałymi przez instrukcje warunkowe, to możesz natrafić na wielokrotne występowanie słów "return". Na przykład 👇:

def get_division_of(a, b):
	if b == 0:
		return 0

	return a / b

i to będzie oznaczało możliwość zwrócenia różnych wartości zależnie od spełnialności warunków 😮. Taka forma jest jak najbardziej poprawna i należy pamiętać, że jeżeli pojawiają się "rozbicia" na różne przypadki (takie jak sytuacja próby podzielenia przez zero), to wtedy należy uwzględnić je wszystkie i uchronić program przed każdą niepożądaną okolicznością ⚠️!

Zależnie od problemu i sposobu pisania, można albo zdefiniować zwracanie różnych wartości (wiele instrukcji "return"), albo odpowiednio modyfikować wartości i zwrócić jedną wartość na samym końcu 💡. W powyższym przykładzie równie dobrze moglibyśmy na początku utworzyć zmienną dla wyniku i odwrócić warunek, tak aby przypisać zmiennej wynik ilorazu, gdy parametr "b" jest różny od zera 👇:

def get_division_of(a, b):
	result = 0

	if b != 0:
		result = a / b

	return result

To dałoby ten sam efekt ✅, choć tutaj wyszło troszeczkę więcej kodu 😝. Chciałem w ten sposób pokazać, że są dwa podejścia obsługi wielu przypadków zwracania wartości przez funkcję 😊.

Funkcja z jednym parametrem zwracająca wartość w języku Python

Funkcja może zwracać wartość jako wynik jakiegoś wyrażenia.

Skoro jesteśmy przy zmiennych w funkcjach, oto kolejny ważny temat jaki trzeba sobie wytłumaczyć ⚠️!

CZYM SIĘ RÓŻNIĄ W JĘZYKU PYTHON ZMIENNE UTWORZONE W FUNKCJI OD ZMIENNYCH UTWORZONYCH NA ZEWNĄTRZ?

Trzeba wiedzieć na temat zmiennych w funkcjach o tym, iż mają tzw. "lokalny zasięg" 😮. To oznacza, że będą one istnieć wyłącznie w obrębie ciała funkcji ⚠️. Natomiast, możemy się odwoływać do zmiennych spoza funkcji w środku funkcji 😱!

Zmienne tworzone na zewnątrz (poza jakąkolwiek strukturą) są dostępne w obrębie całego skryptu i one z kolei mają globalny zasięg 🌐! Z tego względu, do zmiennej zdefiniowanej poza funkcją możemy się odwoływać wewnątrz funkcji 👇:

value = 10

def get_square_of_value():
	return value*value

To się wykona bez problemów ✅. Natomiast gdybyśmy chcieli dokonać modyfikacji 👇:

def modify_value(n):
	value = n

to to już nie przejdzie ⛔! Aby móc swobodnie utrwalać modyfikacje zmiennych wewnątrz funkcji, trzeba sprawić aby zmienna była globalna 💥! W Pythonie używamy do tego słowa kluczowego "global" 👇:

def modify_value(n):
	global value

	value = n

Zmienne globalne to temat na osobny artykuł i tam będzie więcej informacji, ponieważ zbyt daleko odchodzi od funkcji ✋.

Teraz przyjrzymy się wartościom domyślnym parametrów, bo tak się składa, że Python zezwala na przypisywaniu parametrom wartości domyślnej 🎉!

JAK PRZYPISAĆ DOMYŚLNĄ WARTOŚĆ PARAMETROWI FUNKCJI W JĘZYKU PYTHON?

Możesz sprawić, aby funkcja w języku Python przypisała dowolną wartość domyślną danemu parametrowi w sytuacji, gdy nie zostanie ona określona w momencie wywołania 🔥! Wystarczy po podaniu nazwy parametru, wstawić operator przypisania i podać wartość jaka ma być uznana za domyślną 😄! To jest przykład 👇:

def get_square_of(n = 1):
	return n*n

Taki zapis sprawi, że podczas wywoływania funkcji nie dojdzie do próby pomnożenia przez siebie wartości, która nie została zdefiniowana (co natychmiast poskutkowałoby awarią programu ⛔), tylko wówczas zostanie przypisana wartość 1 👍. Python będzie wiedział jaką wartość tam wstawić i parametr przyjmie podstawioną wartość domyślną (zapisaną w definicji) w sytuacji, gdy jej zabraknie w momencie wywołania 🙂.

Osobiście nie polecałbym pisać tak "na wyrost", gdy dotyczy to obowiązkowych czy podstawowych parametrów, aby unikać przypisywania konkretnych wartości podczas wywoływania funkcji, gdyż przy późniejszych zmianach wartości domyślnej będzie to oznaczać katastrofalne skutki we wszystkich wystąpieniach wywołania funkcji. Wtedy trzeba będzie odszukać te wszystkie wywołania i wstawić tę wartość, która była wcześniej ustawiona jako domyślna. Jeżeli jednak z kontekstu wynika, że dany parametr nie jest niezbędny (jest opcjonalny), to wtedy jak najbardziej będzie dobrym pomysłem skorzystanie z wartości domyślnej ✅!

Funkcja z jednym parametrem z wartością domyślną zwracająca wartość w języku Python

Parametry funkcji mogą przyjmować wartości domyślne po przypisaniu ich w miejscu definicji, dzięki czemu zostaną one zastosowane w sytuacji, gdy nie podano żadnej wartości w wywołaniu funkcji.

Wszystko na temat zwracania wartości przez funkcję, tylko jeszcze wspomnę o jednej kwestii, której warto być świadomym/świadomą 🔔.

CO SIĘ STANIE, GDY PRZYPISZEMY WYNIK FUNKCJI NIEZWRACAJĄCEJ WARTOŚCI W JĘZYKU PYTHON?

W tym języku nic. Po prostu wynikiem takiej funkcji będzie wartość "None" - typ danych reprezentujący brak jakiejkolwiek wartości 🙂. Aczkolwiek trzeba wiedzieć, że wiele innych języków będzie na to patrzeć bardziej rygorystycznie i zwyczajnie odmówi uruchomienia programu w momencie próby przypisania wyniku funkcji, która nie zwraca żadnej wartości. Nie ma sensu tak postępować, bo to nie przynosi niczego poza późniejszymi kłopotami 😏.

Dlatego przyjmij do wiadomości, że to w standardzie programowania jest absolutnie niedopuszczalne i nie wolno próbować podstawiać wyniku, którego funkcja wcale nie zwraca ❌. Chyba, że ustalimy, że funkcja zwraca wartość, lecz w skrajnym przypadku może zwrócić wartość "None". Wtedy to już całkiem co innego.

Czas na ostatni fragment związany z definiowaniem funkcji, czyli jakie najlepiej określać dla nich nazwy 🙂!

JAKIE SĄ ZASADY NADAWANIA NAZW FUNKCJOM W JĘZYKU PYTHON?

W języku Python, nazwa funkcji musi bezwzględnie przestrzegać pewnych zasad 🔴, a oprócz tego występują dodatkowe zalecenia odnoszące się do dobrych praktyk 🔵.

Oto zasady nazywania funkcji jakie muszą być przestrzegane, aby program został uruchomiony 👇:

  • nie może zaczynać się od cyfry,
  • nie może zawierać odstępów pomiędzy słowami w postaci spacji bądź tabulatora; wtedy korzystamy ze znaku podkreślenia (_), czyli znaku "podłogi".

Z kolei dobre praktyki jakie nie są obowiązkowe, aczkolwiek wysoce zalecane, są następujące 👇:

  • powinna nieść ze sobą kontekst/znaczenie (innymi słowy, nazwa powinna jednoznacznie określać powód jej istnienia np. "calculate_difference" czy "get_current_tax_rate", abyś od razu wiedział(a) co ona robi),
  • powinna stosować się do konwencji nazewniczej Pythona (pisanie wyłącznie małymi literami i oddzielanie słów znakiem podkreślenia).

Warto wiedzieć jeszcze o poniższych faktach, choć nie warto ich wdrażać do pisania na co dzień 👇:

  • może posiadać znaki diakrytyczne (między innymi polskie znaki),
  • może składać się z więcej niż 255 znaków (przy czym najlepiej dawać krótsze nazwy 🙃).

Co do parametrów funkcji, to obowiązuje takie same zasady jak przy nazywaniu zmiennych, więc przejdź do odpowiedniego artykułu, aby się z nimi zapoznać 👈.

Mamy za sobą wyjaśnioną część dotyczącą definiowania funkcji 😁. Teraz druga część: wywoływanie funkcji, czyli sprawienie, aby wykonały się wszystkie umieszczone tam instrukcje 🚀!

JAK WYWOŁAĆ FUNKCJĘ W JĘZYKU PYTHON?

Wywołanie funkcji, to po prostu skorzystanie z niej. W Pythonie funkcję wywołujemy poprzez wpisanie bezbłędnie jej nazwy i wstawienie pary nawiasów okrągłych 💡. Jeżeli funkcja przyjmuje parametry, to wprowadzamy odpowiednią ich liczbę i typ danych, zgodnie z jej definicją i działaniem 🫵.

Dla przykładu, gdy mamy taką funkcję 👇:

def write_greeting():
	print('Witaj!')

to jej wywołanie będzie wyglądać tak 👇:

write_greeting()

Nazwa i nawiasy okrągłe 🙂. Nieważne, że tu nie ma parametrów. Zawsze dodajemy te nawiasy, gdyż to jest ustandaryzowane oznaczenie wywołania funkcji ⚠️.

Gdy uruchomimy program z powyższymi zapisami, to program "wejdzie" do tej funkcji, wykona wszystkie instrukcje, "wyjdzie" z niej i przejdzie dalej ⏩. W taki sposób to działa 😊!

A teraz przyjmijmy, że mamy funkcję z parametrem 👇:

def write_greeting(name):
	print('Witaj, ' + name + '!')

To wówczas, prawidłowe wywołanie powinno wyglądać następująco 👇:

write_greeting('Jason')

Tak samo nazwa, tak samo nawiasy okrągłe, lecz teraz w środku nich znajduje się wartość 🔥!

Każdorazowo należy podać tyle parametrów, ile wymaga funkcja którą wywołujemy 🫵. Python nie zwróci Tobie uwagi, gdy liczba podanych parametrów nie zgadza się z liczbą oczekiwanych parametrów, także zawsze upewnij się, że parametry są w 100% zgodne pomiędzy wywołaniem, a definicją ⚠️.

To może być też wyrażenie np. wynik zwrócony przez inną funkcję 👇:

write_greeting('Jason'.upper())

albo zmienna 👇:

my_name = 'Jason'

write_greeting(my_name)

Wszystkie kombinacje są dozwolone ✅. Grunt, aby występowała zgodność po stronie typów danych 👍.

Wywołanie funkcji z jednym parametrem niezwracającej żadnej wartości w języku Python

Wywołanie funkcji polega na "uruchomieniu" jej i wykonanie wszystkich zawartych w niej instrukcji.

Gdy funkcja zwraca jakąś wartość, to możemy przypisać jej wynik tam, gdzie chcemy go użyć ❤️! Spójrzmy na taki przykład 👇:

def get_square_of(n):
	return n*n

To jest funkcja, która wylicza kwadrat podanej liczby i zwraca go ↩️. A to oznacza, że jej wynik możemy wstawić w miejsce zmiennej 👇:

squared_number = get_square_of(4)

parametru innej funkcji 👇:

print(get_square_of(4))

bądź użyć jako składnika jakiegoś wyrażenia 👇:

4*math.pi*get_square_of(r)

Wzór na pole powierzchni kuli 🙂.

Oczywiście możesz zignorować jakiekolwiek przypisywanie i po prostu skończyć na samym wywołaniu funkcji 👇:

get_square_of(4)

tylko wtedy jej wynik "przepadnie" i nie odniesie żadnego skutku ℹ️.

Właśnie po to jest to całe zwracanie wartości przez funkcję 😊! Jeżeli dobrze zrozumiesz cały mechanizm zwracania wartości przez funkcje, to będziesz wiedzieć jak działają funkcje matematyczne i wszystkie inne, które przyjmują parametry, wyliczają coś i zwracają gotowy wynik, z którym możemy zrobić co tylko chcemy 🤩!

Wywołanie funkcji z jednym parametrem zwracającej wartość w języku Python

Jeżeli funkcja zwraca jakąś wartość, to możesz przypisać wynik do zmiennej, do innego wyrażenia bądź do wywołania innej funkcji oczekującej wartości tego samego typu.

Dodatkowy mini wątek na temat kolejnej możliwości dostępnej tylko w Pythonie 🎉! Możesz wprowadzać wartości parametrów...w dowolnej kolejności 😱!

JAK W JĘZYKU PYTHON WPROWADZAĆ ARGUMENTY DO FUNKCJI W DOWOLNEJ KOLEJNOŚCI?

Python umożliwia wprowadzanie parametrów do funkcji w dowolnej kolejności stosując tzw. "argumenty nazwane" 🌟. Polega to na poprzedzeniu wprowadzanej wartości nazwą parametru określoną w definicji funkcji i operatorem przypisania (znak równości)!

Gdy mamy taką funkcję 👇:

def get_power_of(a, n):
	return a ** n

to stosując argumenty nazwane, możemy wywołać ją w taki sposób 👇:

print(get_power_of(n = 4, a = 2))

Po prostu podaliśmy parametry w odwrotnej kolejności, lecz nic złego się nie stanie i po uruchomieniu takiego wywołania, wynik będzie całkowicie poprawny i równy 16 ✔️.

To jest równoważne temu wywołaniu 👇:

print(get_power_of(2, 4))

Argument nazwany może być zastosowany też wobec wywołania funkcji z jednym parametrem, choć jak zapewne się domyślasz, nie będzie najmniejszego sensu tak pisać 😉.

Możemy połączyć ten zapis z zapisem tradycyjnym i sprawić, aby było pół na pół - argumenty nazwane połączone z argumentami pozycyjnymi (wartości wstawiane bez nazwy ℹ️). Dużo lepiej będzie to pokazać na przykładzie funkcji z trzema parametrami 3️⃣. Oto ona 👇:

def get_expression_value(a, b, c):
	return a*b + c

Mamy kilka sposobów zapisu i wszystkie poniższe dadzą ten sam wynik 👇:

print(get_expression_value(1, 2, 3))
print(get_expression_value(a = 1, b = 2, c = 3))
print(get_expression_value(c = 3, b = 2, a = 1))

Natomiast możemy też napisać tak 👇:

print(get_expression_value(1, c = 3, b = 2))

Tutaj pominęliśmy nazwę dla pierwszego parametru i to też zostanie przyjęte ✅. Jednak tu już występuje takie ograniczenie, że argumenty pozycyjne (same wartości bez nazwy ℹ️) nie mogą występować przed argumentami nazwanymi, także taka sytuacja 👇:

print(get_expression_value(a = 1, 2, 3))

już zakończy się błędem typu "SyntaxError" i przerwaniem programu, jeśli nie przechwytujemy wyjątku 🚫! Błąd pojawi się również wtedy, gdy niechcący przypiszesz wiele razy wartość do tego samego parametru (wtedy będzie to "TypeError") 💥!

Wywołanie funkcji z trzema parametrami zwracającej wartość z argumentami nazwanymi w języku Python

Możesz wprowadzić parametry funkcji w dowolnej kolejności stosując argumenty nazwane. Oprócz samej wartości, wyróżnia się też nazwą parametru zgodnego z definicją funkcji i operatorem przypisania.

To dodałem jako ciekawostkę i nie radzę tak pisać na co dzień, bo to tylko niepotrzebnie zaciemnia rozumienie kodu ❌.

KIEDY NAJLEPIEJ ZASTOSOWAĆ ARGUMENTY NAZWANE W JĘZYKU PYTHON?

Wtedy, gdy funkcja przyjmuje dużo parametrów, większość z nich posiada wartości domyślne, a my chcemy ustawić wartość tylko jednemu z nich bez powielania tego samego ciągu co każde wywołanie tylko po to, aby się "dostać" do tego parametru, o który nam chodzi ✅. To tak jednym zdaniem w jakiej sytuacji najlepiej z tego skorzystać (moim zdaniem) 😉.

Warto jeszcze wspomnieć o istotnej rzeczy dotyczącej samego miejsca wywołania funkcji, o której też trzeba wiedzieć 😮!

W KTÓRYM MIEJSCU POWINNO SIĘ ZNALEŹĆ WYWOŁYWANIE WŁASNEJ FUNKCJI W JĘZYKU PYTHON?

W Pythonie, miejsce wywołania naszej funkcji ma duże znaczenie i od niego zależy, czy program w ogóle się uruchomi 😳! Wywołanie danej funkcji będzie możliwe tylko, gdy znajdzie się w kodzie później, niż definicja 💥!

Oto przykład kodu, aby zobrazować o co mi chodzi 👇:

def write_greeting():
	print('Witaj!')

write_greeting()

W powyższym przykładzie, definicja znajduje się wyżej niż wywołanie i to wykona się bez problemu 👍. A popatrz tutaj 👇:

write_greeting()

def write_greeting():
	print('Witaj!')

To wywoła awarię programu i zatrzymanie go przez błąd typu "NameError" (brak definicji dla podanej nazwy) ❌! Aby zrozumieć dlaczego, musimy mieć pojęcie o działaniu interpretera, gdyż Python należy do języków interpretowanych 👀!

Interpreter jest programem przetwarzającym instrukcje skryptów jeden wiersz po drugim "na żywo". Stąd też, gdy poczynając przetwarzanie zawsze od samej góry, trafia na wywołanie funkcji, w danym momencie nie ma pojęcia czym jest to hasło ❓. Dlatego tak ważne jest trzymanie się zasady: "najpierw definicja, potem wywołanie" 💡.

To cała teoria o funkcjach, jaką chciałem przedstawić 😁. Wyszedł ogrom informacji, natomiast mam nadzieję, że będzie w stanie odpowiedzieć na wszystkie nurtujące Cię pytania, teraz i w przyszłości 👍.

Teraz czas na prosty przykład praktyczny 🔥!

PRZYKŁAD UŻYCIA FUNKCJI W JĘZYKU PYTHON

Sięgniemy po przykład użycia dla matematycznej funkcji kwadratowej i wyznaczaniu wartości dla danego argumentu x 😊! Oto kod, który wypisuje w konsoli wartości funkcji kwadratowej dla argumentów x, zależnie od zmiennej oznaczającej liczbę argumentów od argumentu zerowego, czyli <-N; N> 👇:

a = 1
b = 0
c = 0
number_of_arguments_from_origin = 2

def get_value_of_argument(x):
	return a*x**2 + b*x + c

for x in range(-number_of_arguments_from_origin, number_of_arguments_from_origin + 1):
	print('f(' + str(x) + ') = ' + str(get_value_of_argument(x)))

Wyjaśniam treść kodu 📣!

Na samej górze znajduje się seria zmiennych. Pierwsze 3 określają wartości wyrazów funkcji kwadratowej (a, b, c), a ostatnia określa nam liczbę argumentów (oś X) od argumentu zerowego (x = 0), która przyda się nam do wyznaczenia zakresu liczb dla pętli "for" 👍.

Pośrodku mamy definicję funkcji do obliczania wartości funkcji kwadratowej dla podanego argumentu x, którą zwraca na wyjściu 🙂. Zauważ, że wyrazy a, b i c są umieszczone poza funkcją! Ponieważ zostały one określone wcześniej i na zewnątrz jakiegokolwiek bloku kodu, to zostaną poprawnie zidentyfikowane jako te zmienne znajdujące się na samej górze i Python nie będzie zgłaszał żadnych roszczeń 😉.

Na samym końcu mamy pętlę "for" operującą na zakresie liczbowym ("range"), który przyjmie wartości zależnie od wartości zmiennej określającej liczbę argumentów od argumentu zerowego, czyli w przedziale od -N do N ✔️. Jeżeli się dobrze przyjrzałeś(-aś) definicji zakresu, to zauważyłeś(-aś) zwiększenie górnej granicy o jeden 😮. To jest niezbędny zabieg, ponieważ "range" nie uwzględnia górnej granicy (jest nazywana jako "exclusive end" ℹ️) 🔥! Dlatego aby mieć pewność, że zakres będzie brał pod uwagę górną granicę równą N, a nie N - 1, dodajemy jedynkę 📈.

W środku pętli "for" mamy tylko wywołanie funkcji "print", która posiada bardziej złożone wyrażenie do uzyskania treści w takiej formie 👇:

f(x) = [wartość funkcji dla argumentu x]

czyli tak, jak się pisze w matematyce 🙂. Wśród konkatenacji łańcuchów znaków, mamy też wywołanie funkcji do wyznaczania wartości funkcji dla zadanego argumentu x i to jest ten fragment 👇:

get_value_of_argument(x)

I to wszystko. Po uruchomieniu tego programu, ujrzysz w konsoli wiersze postaci ukazanej u góry, dla kilku argumentów z przedziału <-N; N> 😊. Czyli napisaliśmy jeden raz instrukcję do wyliczania wartości funkcji kwadratowej, której mogliśmy użyć wielokrotnie w pętli "for" 🤩!

Zanim zakończę już i tak długi materiał o funkcjach w Pythonie 😝, ostatnia rzecz przed jaką chcę Cię uprzedzić ⚠️.

CZYM SIĘ RÓŻNI FUNKCJA W JĘZYKU PYTHON OD INNYCH JĘZYKÓW?

Gdy kiedykolwiek zaczniesz się uczyć kolejnego języka zaraz po Pythonie, musisz się liczyć z tym, że dostrzeżesz zupełnie inną postać od tej, jaka obowiązuje tutaj 😳! W wielu innych językach programowania poza opisanymi elementami, trafisz także na konieczność określenia typu danych jaki ma zwracać funkcja. W Pythonie zostało to scalone do jednego słowa "def", natomiast standardowo występuje podział na 2 typy danych dla funkcji 👇:

  • "void" = funkcja niezwracająca wartości,
  • dowolny typ danych niebędący "void" = funkcja zwracająca wartość.

Dlatego trzeba być przygotowanym na to, że w trakcie nauki nieco bardziej restrykcyjnego języka, trzeba będzie się liczyć z inną budową funkcji ⚠️. Zapraszam do artykułu tłumaczącego funkcje ogólnie w programowaniu 👈.


W końcu doszliśmy do mety 😅! Jak widzisz, funkcja w języku Python wymaga przyswojenia sporego zastrzyku wiedzy, tak abyśmy wiedzieli czym ona jest, do czego służy oraz czym jest definicja i wywoływanie 🔥. Wszystko złożone w jedną całość, tworzy nam ciąg zdarzeń jaki musisz sobie przyswoić, aby potem robić to automatycznie ⏩.

PODOBNE ARTYKUŁY