Monday, December 22, 2008

Python - funkcje i zmienne z punktu widzenia C++

Będąc pod wrażeniem Thinking in Python chciałem tym wpisem rozpocząć pewne rozważania, które powinny być spostrzeżeniami programisty C/C++ po zderzeniu się z językiem Python.

Języki C/C++ wymagały od nas definiowania funkcji w bardzo restrykcyjny sposób. Musieliśmy podać dokaładnie typ i kolejność przekazywanych parametrów. Zmiana, którejś z tych dwóch powodowało przeładowywanie funkcji. Dodatkowo wymagane było od nas podanie wartości, którą miała zwracać nasza funkcja. Przez co czasami musieliśmy pisać kilka wersji naszej funkcji.

W języku Python wszystko wygląda znacznie prościej. Dlaczego ? Otóż tak jak w języku C/C++ zmienne posiadały konkretny typ - taki a nie inny, w języku Python spotykamy się z pewną szczególną cechą zmiennych. Po pierwsze nie definiujemy explicite ich typów. Są one "rozpoznawane" a może raczej "przyjmowane" przez język programowania na podstawie wartości jakie im przypiszemy.

Co to dla nas oznacza ? Aby w C/C++ stworzyć jakąś uniwersalną funkcję działającą dla różnych typów przekazywanych do niej obiektów musieliśmy używać mechanizmu szablonów. Ponieważ tutaj tworząc funkcję nie podajemy typów parametrów jakie przekazujemy - nasza funkcja działa dla wszystkich danych dla niej przekazanych - o ile operacje, które w niej wykonujemy mają dla tych zmiennych sens.

Dobrym przykładem prezentującym jest na przykład operacja "dodawania" (+).
Dla zmiennej typu string oznacza ona konkatencję (połączenie dwóch napisów).
Dla liczb oznacza to naturalnie ich dodanie.

Rozważmy funkcję dodającą dwie wartości:


def add(a, b):
    return a + b


Nigdzie nie podaliśmy typu zmiennej. Super spróbujmy więc podać wartości różnych typów - zobaczymy co dostaniemy:

add(2,3)

zwróci nam na pewno 5. No dobrze, ale czy zadziała dla liczb zmiennoprzecinkowych ? Oczywiście - jedyny wymaganiem Pythona jest tutaj aby operator, którego używamy (u nas +) był dobrze zdefiniowany dla obiektów, które przekazujemy do funkcji :) z liczbami rzeczywistymi nie ma tutaj problemu.

add(0.1,7.4)

da nam 7.5 :] pięknie. Ba więcej !

add((3 + 2j), (7 + 1.7j))

da nam równie dobry wynik - (10 + 3.7j) :] zgodnie z zasadą - jeżeli dla jakiegoś typu przekazanego do funkcji operacje, które na nim wykonujemy są dobrze określone - wszystko zadziała.
Do tej pory używaliśmy tylko parametrów liczbowych :) Jednak gdyby tak pomyśleć - to operator + jest równie dobrze określony dla napisów - oznacza on po prostu ich konkatenację. Czyli "Merry" + " Christmas" powinno nam wyprodukować "Merry Christmas". Sprawdźmy.

add('Marry', ' Christmas')

Działa :)

Jak widać Python pozawala na tworzenie funkcji, których zachowanie jest bardziej naturalne a wyniki dokładnie takie jakie się spodziewamy :] Specjalne mechanizmy, które służyły nam do osiągnięcia podobnego efektu w C++ zostały jakby "wchłonięte" w naturalne zachowanie się języka programowania.
Zasada iż operatory i działania jakie wykonujemy na obiektach przekazywanych do funkcji tyczy się również tworzonych przez nas typów. Python pozwala na przeładowywanie i definiowanie całego grona operatorów pozwalających nam sterować zachowywaniem się tworzonym przez nas typów danych. Jedną z dostępnych w dokumentacji list takich operatorów znajdziesz pod adresem http://docs.python.org/library/operator.html

No comments: