JEZYK PROGRAMOWANIA PYTHON: WPROWADZANIE DANYCH I FORMATOWANIE WYNIKÓW, WEWNETRZNA DOKUMENTACJA, PROGRAMY I MODUŁY E. Dyguda-Kazimierowicz 1 Formatowanie danych wyjściowych Do formatowania wyświetlanych wyników służy dwuargumetowy operator % (kolejny przykład przeciążania operatorów). Jego działanie polega na przekształceniu (formatowaniu) łańcucha podanego po lewej stronie z wykorzystaniem zastępczych wartości wymienionych po prawej. Wynikowy napis można wyświetlić (np. za pomocą instrukcji print) lub przypisać zmiennej: >>> imie, ilosc_kotow = "Ala", 7 >>> print "%s ma %d kotow" % (imie, ilosc_kotow) >>> tekst = "%d: tyle kotow ma %s" % (ilosc_kotow, imie) >>> print tekst 7: tyle kotow ma Ala Formatowany łańcuch (lewy operand), oprócz zwykłego tekstu wyświetlanego w niezmienionej postaci, zawiera tzw. ciagi (pola) formatujace, których liczba musi odpowiadać liczbie pozycji zgrupowanych w nawiasach jako prawy operand. Ciąg formatujący (np. %s) rozpoczyna się znakiem %, po nim opcjonalnie wstawia się modyfikatory sterujące sposobem wyświetlania danych, na końcu podana jest litera określająca typ przekształcenia w powyższym przykładzie napis imie wstawiany jest do łańcucha w miejsce "%s", a liczba całkowita ilosc_kotow zastępuje ciąg %d. Analogicznie wstawia się do łańcucha liczby zmiennoprzecinkowe (%f, %g, %e lub %E polecam samodzielne sprawdzenie różnic między wynikowymi formatami), liczby całkowite ósemkowe (%o) i szesnastkowe (%x albo %X), pojedyncze znaki (%c), a także literał % (%%). Liczba wstawiona między znak % i literę definiującą przekształcenie oznacza szerokość pola, dodatkowo poprzedzenie jej kropką pozwala określić dokładność (następuje zaokrąglenie wyniku zmien- 1
1 FORMATOWANIE DANYCH WYJŚCIOWYCH noprzecinkowego do żądanej liczbę miejsc znaczących, domyślnie 6). Wynik przekształcenia wyrównywany jest do prawej aby to zmienić, wystarczy wstawic znak "-" po znaku "%". W tym samym miejscu może się też pojawić "+" (poprzedzanie liczb, również dodatnich, ich znakiem), "0" (poprzedzanie liczb zerami aż do wypełnienia zadanej szerokości pola) oraz spacja (wstawianie znaku spacji przed liczbami dodatnimi i pustymi łańcuchami): >>> x, y = 123456, 123.456 >>> s = "python" >>> print "[%10d]\n[%10f]\n[%10s]" % (x, y, s) [ 123456] [123.456000] [ python] >>> print "[%.2d]\n[%.2f]\n[%.2s]" % (x, y, s) [123456] [123.46] [py] >>> print "[%10.2d]\n[%10.2f]\n[%10.2s]" % (x, y, s) [ 123456] [ 123.46] [ py] >>> print "[%-10.2d]\n[%-10.2f]\n[%-10.2s]" % (x, y, s) [123456 ] [123.46 ] [py ] >>> print "[%-+10.2d]\n[%010.2f]\n[%.2f]" % (x, y, y) [+123456 ] [0000123.46] [ 123.46] >>> print "[%7c]\n[%7o]\n[%7d]\n[%7x]" % (70, 70, 70, 70) [ F] [ 106] [ 70] [ 46] 2
3 ATRYBUTY OBIEKTÓW: WEWNETRZNA DOKUMENTACJA 2 Wprowadzanie danych Komunikację użytkownika z programem, czyli pobieranie danych ze standardowego wejścia, umożliwiają funkcje raw_input() i input(). Pierwsza z nich zwraca łańcuch, natomiast druga interpretuje typ wprowadzanego obiektu zgodnie z regułami Pythona (patrz poniższe przykłady). Opcjonalnym argumentem dla obu funkcji jest łańcuch wyświetlany podczas oczekiwania na podanie danych: >>> a, b = raw_input( Liczba: ), raw_input( Napis: ) Podaj liczbe: 100 Podaj napis: sto >>> type(a), type(b) (<type str >, <type str >) >>> A, B = input( Liczba: ), input( Napis: ) Podaj liczbe: 100 Podaj napis: sto >>> type(a), type(b) (<type int >, <type str >) Funkcja input() wymaga od użytkownika znajomości składni Pythona: wpisanie w powyższym przykładzie napisu sto bez apostrofów wyświetli komunikat o błędzie. Bezpieczniej jest zatem korzystać w programach z funkcji raw_input(), należy jednak pamiętać o konwersji wprowadzonych danych do określonego typu. Funkcja input() jest w rzeczywistości równoważna działaniu funkcji eval() na łańcuch zwrócony przez raw_input() działanie tej funkcji polega na interpretowaniu i obliczaniu wyrażeń, w których skład wchodzić mogą zmienne, funkcje i struktury danych: >>> X, Y, S = 3.14, -1, jakis tam napis >>> policz = input() #rownowazne: eval(raw_input()) X*Y - 10 + len(s) >>> print policz 1.86 3 Atrybuty obiektów: wewnętrzna dokumentacja Wbudowana funkcja dir() zwraca listę atrybutów obiektu podanego jako argument. Atrybuty to nazwy związane z obiektem (np. nazwy jego zmiennych, funkcji, klas). Poniżej funkcję dir() wywołano z obiektem typu łańcuchowego (pustym napisem): 3
4 IMPORTOWANIE MODUŁÓW, MODUŁ MATH >>> dir( ) [ add, class, contains, delattr, doc, #...tu usunieto fragment capitalize, center, count, decode, encode, endswith, #...itd... Analogicznie uzyskać można atrybuty np. metody łańcuchowej capitalize: >>> dir(.capitalize) [ call, class, cmp, delattr, doc, getattribute, hash, init, module, name, new, reduce, reduce_ex, repr, self, setattr, str ] Wyrażenie obiekt.atrybut (tzw. kwalifikacja nazw) umożliwia dostęp do określonego atrybutu danego obiektu (np..capitalize. doc z poniższego przykładu pobiera wartość przypisaną do doc w metodzie capitalize obiektu łańcuchowego). Warto zwrócić uwagę na dwa atrybuty występujące w prawie każdym obiekcie: łańcuch dokumentacji doc oraz łańcuch będący po prostu nazwą obiektu, czyli name : >>> print.capitalize. doc S.capitalize() -> string Return a copy of the string S with only its first character capitalized. W ubiegłym tygodniu pokazano przykład użycia funkcji dir() do wyświetlenia nazw zmiennych zdefiniowanych podczas interakcyjnej pracy interpretera (w globalnej przestrzeni nazw). Listę nazw z wbudowanej przestrzeni nazw (tzn. wszystkie nazwy wstępnie zdefiniowane przez Pythona) zwraca dir( builtins ). W ten sposób można np. sprawdzić dostępne funkcje wbudowane, a następnie przejrzeć ich dokumentację. 4 Importowanie modułów, moduł math Za pomocą funkcji wbudowanych w Pythonie można zrobić stosunkowo niewiele. Wbudowane funkcje matematyczne pozwalają obliczyć wartość bezwzględną liczby, porownać dwie liczby czy znaleźć minimalną (maksymalną) wartość w sekwencji liczb (odpowiednio abs(x), cmp(x1,x2), 4
5 WŁASNE MODUŁY (PROGRAMY) min(x1,x2,x3), max(x1,x2,x3s)), ale już obliczenie dowolnej funkcji trygonometrycznej jest niemożliwe. Zaletą takiej strategii jest oszczędność w gospodarowaniu zasobami pamięci: funkcje używane tylko w niektórych przypadkach nie są niepotrzebnie ładowane do pamięci. Z Pythonem rozprowadzany jest natomiast cały szereg bibliotek (modułów), udostępniających mnóstwo funkcji wykorzystywanych w rozmaitych typach zadań programistycznych. Wspomniane funkcje trygonometryczne znajdują się w module math. Aby z nich skorzystać, należy ten moduł zaimportować (załadować do pamięci interpretera) za pomocą instrukcji import, a podczas wywoływania danej funkcji pokazać Pythonowi jej lokalizację, stosując opisaną powyżej kwalifikację nazw: >>> import math >>> print math.pi #liczba pi (stala zmiennoprzecinkowa) 3.14159265359 >>> print math.sin(math.pi/6) #argument: kat w radianach 0.5 >>> x=1 >>> print math.log(x) #logarytm naturalny 0.0 >>> print math.exp(x) #funkcja eksponencjalna 2.71828182846 Zamiast importować moduł w sposób przedstawiony powyżej, można pobrać tylko potrzebne w danym momencie obiekty unika się tym samym konieczności kwalifikowania nazw (tzn. nazwy obiektów używane są bezpośrednio): >>> from math import pi, sin >>> print sin(pi/2) 1.0 W analogiczny sposób działa wyrażenie "from math import *" zamiast ładowania określonych nazw, pobierane są wszystkie nazwy obiektów z modułu math. 5 Własne moduły (programy) Programy w języku Python określane są często jako skrypty lub moduły (pliki modułowe). Z technicznego punktu widzenia są to zwykłe pliki tekstowe z kodem źrodłowym w tym języku, uruchamiane poleceniem python nazwa_programu wpisywanym z poziomu powłoki w Linuksie lub w wierszu poleceń DOS (wymaga to oczywiście zainstalowanego interpretera Pythona): 5
5 WŁASNE MODUŁY (PROGRAMY) prkom1:~$ cat moj_program.py x, y, imie = 2, 5, Ala print "%s ma %d kotow" % (imie, x + y) prkom1:~$ python moj_program.py W systemach Unix/Linuxplik z kodem w Pythonie można zamienić na plik wykonywalny i uruchamiać potem jak każdy plik wykonywalny w tych systemach, Należy w tym celu w pierwszej linii wpisać po znakach #! ścieżkę dostępu do interpretera Pythona (można ją uzyskać poleceniem which python) oraz nadać plikowi atrybut wykonywalności: prkom1:~$ cat moj_program.py #!/usr/bin/python x, y, imie = 2, 5, Ala print "%s ma %d kotow" % (imie, x + y)$ prkom1:~$ chmod +x moj_program.py prkom1:~$./moj_program.py Pierwszy wiersz w powyższym pliku stanowi informację dla powłoki o tym, co zrobić z zawartością pliku (dla interpretera języka Python jest to zwykły komentarz); podaną tu ścieżkę należy traktować jako przykład. Aby uniknąć jawnego wpisywania ścieżki dostępu, można skorzystać z programu env, który wyszukuje w dostępnych ścieżkach program podany jako argument. W praktyce sprowadza się to do zastąpienia ścieżki do interpretera lokalizacją programu env oraz argumentem dla tego programu (czyli nazwą interpretera python): #!/usr/bin/env python Programy w Pythonie można wreszcie zaimportować do interpretera pracującego w trybie interaktywnym lub wstawić instrukcję importu do dowolnego innego kodu źrodłowego Pythona. W obu przypadkach wymagana jest nazwa pliku zgodna z regułami tworzenia nazw zmiennych w Pythonie, zakończona rozszerzeniem ".py". Pierwszy import modułu powoduje uruchomienie całego zawartego w nim kodu, od tego moment uzyskuje się też dostęp do nazw zdefiniowanych w module: >>> import moj_program >>> print moj_program.x, \n, moj_program.imie 2 Ala 6