Bieżący rozdział poświęcony jest technicznym aspektom tworzenia i uruchamiania programów. Proponujemy naukę podstaw programowania w języku Python.
Rozpoczynamy od omówienia zestawu oprogramowania służącego temu celowi i od opisu jego instalacji. Następnie zaznajamiamy czytelnika z trybem interaktywnej współpracy z konsolą Pythona. W dalszej kolejności omówione są metody uruchamiania programów źródłowych oraz podstawowe konstrukcje języka.
Python jest językiem stosunkowo młodym; opracowany został w latach 90-tych XX wieku. Jego rosnąca popularność wynika z prostej składni, czytelnej notacji, swobody pozostawianej autorom kodu i bogatego zaplecza (batteries included).
Logo Pythona |
---|
Python jest językiem ogólnego przeznaczenia. Może służyć do przekształcania danych z pewnego formatu do innego, do prowadzenia obliczeń, do współpracy z systemami baz danych i z aplikacjami użytkowymi. Bywa stosowany do pisania graficznych konfiguratorów i instalatorów w systemach operacyjnych, do tworzenia graficznych interfejsów obsługi, do złożonych serwisów WWW, do symulacji komputerowej i wizualizacji zjawisk fizycznych oraz do wielu innych celów.
Nie ma znaczenia, z jakiego sprzętu i systemu operacyjnego korzystasz. Pythona możesz używać w systemach MacOS X, UNIX, Windows i kilku innych. Ten sam kod źródłowy, o ile został starannie napisany, bez wprowadzania zmian będzie się dało uruchomić w każdym spośród wymienionych systemów.
Dzięki liberalnej licencji użytkowania, z pracą w środowisku Python nie wiąże się konieczność zakupu dodatkowego oprogramowania. Istnieje komercyjne oprogramowanie przeznaczone do pisania i testowania kodu, ale nie jest ono niezbędne; także niektóre biblioteki użytkowe mogą wymagać zakupu licencji.
Całe niezbędne oprogramowanie można pobrać z wymienionych niżej
węzłów dystrybucyjnych. Użytkownicy laboratoriów wydziałowych mogą
pobrać większość niezbędnych pakietów instalacyjnych z naszego serwera
http spod adresu
http://mat.up.wroc.pl/software/byvendor/python
.
Interpreter języka jest najważniejszym, i jedynym naprawdę niezbędnym do nauki w ramach tego kursu, pakietem oprogramowania.
Współczesna wersja języka i interpretera jest oznaczona numerem 3. Aktualizację opatrzoną numerem 3.12.0 wydano w październiku 2023 roku. Aktualizacja wersji linii 3.12 jest zagwarantowana do października 2028 (https://python.org/downloads). Aktualizowane są również wersje: 3.11 (do października 20276), 3.10 (do października 2026), 3.9 (do października 2025), oraz 3.8 (do października 2024).
Rozwój poprzedniej wesji języka został ostatecznie zakończony na wydaniu 2.7.18 w kwietniu 2020 roku. Różni się ona od wersji bieżącej w wielu istotnych szczegółach. Z przyczyn historycznych niniejszy tekst zawiera — co prawda już nieliczne — odwołania do wersji 2. Miejsca, w których różnice między wersjami języka są istotne, zostały oznaczone w tekście.
Istnieje kilka źródeł pakietów instalacyjnych:
http://www.python.org/ftp/python/
)http://www.continuum.io
)http://www.activestate.com/Products/activepython/
)http://www.pypy.org
)O różnych implementacjach interpreterów języka i o sposobach ich pozyskania traktuje rozdział Alternative Python Implementations dokumentacji firmowej.
Z uwagi na fakt, że kod źródłowy programów tworzonych przez użytkownika jest przechowywany w zwykłych plikach znakowych, nie ma potrzeby posiadania specjalnego edytora. Mimo to wygodnie jest korzystać z edytora wzbogaconego o wyspecjalizowane funkcje związane z konkretnym językiem programowania.
Poniżej krótki, i oczywiście niepełny, wybór takich edytorów.
Edytory z tej grupy są wyposażone w narzędzia pomocne przy tworzeniu kodu w języku Python, chociaż nie jest to ich główne przeznaczenie.
http://www.scintilla.org/SciTE
)http://bluefish.openoffice.nl/
)http://notepad-plus.sourceforge.net/
)http://www.vim.org
)Edytory z tej grupy są zaprojektowane specjalnie dla tworzenia kodu w języku Python.
http://wingware.com/downloads/wingide-101
)http://www.activestate.com/komodo_edit
)Edytor jest niezbędny przy tworzeniu kodu programu, a niekiedy także pozwala na jego uruchomienie. Środowisko diagnostyczne umożliwia przetestowanie działania napisanego kodu. Zazwyczaj, choć nie zawsze, jest ono wyposażone we własny edytor.
http://www.digitalpeers.com/pythondebugger/
)http://www.scipy.org/
)http://matplotlib.sourceforge.net/
)http://gnuplot-py.sourceforge.net/
)https://pypi.python.org/pypi/Pillow/
)http://www.ferg.org/easygui
, http://easygui.sourceforge.net
)http://initd.org/pub/software/psycopg/
)http://www.scipy.org/
)http://www.sympy.org/
)http://starship.python.net/crew/mhammond/win32
)http://starship.python.net/crew/theller/comtypes/
)http://www.openoffice.org
)http://pypi.python.org/pypi/SDXF
, http://download.berlios.de/python/sdxf.py
)dxf
będący częścią pakietu graficznego BlenderKolejność instalacji: interpreter, środowisko edycyjne, biblioteki.
Po pomyślnej instalacji pakietów zalecam:
PATH
)
pozwalających na uruchamianie programów python
i pythonwin
z wiersza poleceń (np. cmd
lub bash
).
W systemach uniksowych jest to robione domyślnie;
podobnie w przypadku instalacji Pythona 3 w systemach Windows;easygui.zip
do podkartoteki
Lib/site-packages
lub site-packages
w kartotece macierzystej Pythona;*.py
były domyślnie „otwierane za pomocą”
wybranych przez Ciebie edytorów (np. SciTE
i PythonWin).
Rozpoczęcie pracy interpretera Pythona
polega na uruchomieniu programu o nazwie (zależnie od systemu operacyjnego) python
albo python3
.
Można w tym celu posłużyć się wierszem poleceń powłoki systemowej,
np. uniksowej powłoki bash
[ja@komp sources]$ python3
albo windowsowej cmd
c:\Users\Ja\sources> python
choć jest też wiele innych sposobów. Po uruchomieniu powinniśmy w konsoli zobaczyć znak zgłoszenia interpretera Pythona
Zakończenie pracy interpretera wymusimy za pomocą funkcji systemowej Pythona
exit()
lub wpisując do konsoli Pythona znak sterujący oznaczający koniec danych; w systemach Windows jest to
<Ctrl>Z
zaś w systemach uniksowych
<Ctrl>D
Znaczenie słów kluczowych i reguły ich użycia są zdefiniowane na poziomie języka. Znaczenia tego nie wolno zmieniać, co oznacza m.in., że słowa kluczowe nie mogą być nazwami zmiennych, modułów, argumentów podprogramów ani żadnych innych obiektów w kodzie źródłowym.
Dokumentacja różnych wersji Pythona wymienia następujące słowa kluczowe:
Podstawowe znaczenie słów oznaczonych symbolem
jest objaśnione w toku niniejszego kursu.
Słowa oznaczone symbolem
nie są objaśnione ani używane podczas kursu.
W Pythonie 3 zestaw słów kluczowych kilkakrotnie podlegał modyfikacji. Nowe słowa wyróżniono w powyższym spisie kolorem zielonym; słowa usunięte oznaczono kolorem szarym. Pozostałe słowa należą do wersji 2 i 3 języka.
Przypomnijmy, że komentarze nie wpływają na tok czynności opisany w programie. Ich rola polega na dokumentowaniu sposobu działania programu.
W Pythonie istnieją dwa rodzaje komentarzy:
#
aż do końca wiersza włącznie
instrukcja # tekst aż do końca bieżącego wiersza jest komentarzem
(w istocie taki tekst jest daną typu napisowego, która w niektórych sytuacjach pełni rolę komentarza).""" komentarzem jest tekst znajdujący się pomiędzy ogranicznikami o postaci potrójnych cudzysłowów technicznych. """ ''' zamiast cudzysłowów można także użyć ograniczników o postaci potrójnych apostrofów. '''
Przy poszukiwaniu informacji na temat elementów języka i dostępnych struktur danych
przydatne są funkcje help()
i dir()
:
help() help(obiekt)
Funkcja help()
udostępnia systemowy opis wskazanego obiektu.
W przypadku, kiedy nazwa obiektu nie została podana, opis dotyczyć będzie
sesji Pythona.
dir(obiekt) dir()
Funkcja dir()
udostępnia spis zawartości wskazanego obiektu.
W przypadku, kiedy nazwa obiektu nie została podana, dostaniemy spis
obiektów dostępnych w bieżącej sesji Pythona.
Najprostszym sposobem użycia interpretera jest wykorzystanie go w roli kalkulatora obliczającego na bieżąco wartości wyrażeń różnych typów.
Spacje między wartościami i symbolami działań nie są istotne. Zakończenie wiersza (Enter) wymusza jego interpretację.
1+2+3 6 3/4 0 3.0/4 0.75 float(3)/4 0.75 float(3/4) 0.0 2**(1/2) 1 2**0.5 1.4142135623730951 2**3.0 8.0 '1' + '2' + '3' '123' 'A' + 'l' + 'a' 'Ala'
Jak widać, wyniki obliczane przez ten kalkulator nie zawsze są tym, czego się spodziewamy. Żeby zrozumieć zasady obliczania, musimy powrócić do pojęcia typu danych, i zrozumieć, w jaki sposób typy danych są zrealizowane w Pythonie.
W tym rozdziale usystematyzujemy wiedzę na temat podstawowych typów danych dostępnych w Pythonie. Niezbędna jest znajomość charakterystyk typów danych, przynajmniej w zakresie opisanym w rozdziale 2. oraz elementarne doświadczenie w pracy z konsolą Pythona (choćby po to, by umieć rozpocząć i zakończyć sesję).
Jak już stwierdzono wcześniej, istotą typu danych jest:
W Pythonie każda wartość należy do pewnego typu danych.
Typ można sprawdzić za pomocą instrukcji type(obiekt)
,
na przykład:
type(1) <type 'int'> type(1.0) <type 'float'> type('1') <type 'str'> type(True) <type 'bool'> type(None) <type 'NoneType'>
Niżej charakteryzujemy najważniejsze standardowe (tzn. wbudowane w język) proste (tzn. takie, że należące do nich wartości nie posiadają rozbudowanej struktury wewnętrznej) typy danych dostępne w Pythonie.
Python w weersji 3 oferuje typ danych całkowitoliczbowych
bez wskazania ograniczenia zakresu wartości.
Ograniczeniem wartości typu long
jest jedynie ilość dostępnej
pamięci operacyjnej w systemie.
Działania
a + b # dodawanie liczb a - b # odejmowanie liczb a * b # mnożenie liczb a / b # dzielenie liczb całkowitych daje wynik zmiennopozycyjny a // b # dzielenie całkowite a % b # reszta z dzielenia a przez b a ** b # potęgowanie liczb
W Pythonie 3 operator dzielenia /
daje wynik będący liczbą zmiennopozycyjną.
Warto więc używać operatora //
za każdym razem, kiedy zależy nam
na wyniku całkowitoliczbowym.
Odstępy między symbolem działania a jego argumentami nie mają znaczenia; zostały wstawione dla zwiększenia czytelności.
Kolejność operacji jest określona przez twórców konkretnego języka lub środowiska. W Pythonie jest ona zgodna z tradycyjną notacją matematyczną, przyznającą priorytety poszczególnym działaniom arytmetycznym. Operacje dodawania i odejmowania mają priorytet niższy, niż operacje mnożenia i dzielenia, te zaś z kolei ustępują priorytetem operacji potęgowania. Przy tym samym priorytecie, działania wykonywane są w kolejności czytania tekstu „od lewej do prawej”.
Chcąc wymusić inną kolejność działań, należy użyć nawiasów okrągłych. Nawiasy takie wolno zagnieżdżać.
Jeżeli zapis liczby całkowitej rozpoczyna się cyfrą 0
,
to interpreter Pythona w wersji 2.x języka
przyjmował, że liczbę tę podano w systemie ósemkowym.
Przy takim zapisie wolno używać jedynie cyfr od 0 do 7.
12 12 # tj. 1*10 + 2*1 012 10 # tj. 1*8 + 2*1 29 29 029 File "<stdin>", line 1 029 ^ SyntaxError: invalid token # w systemie ósemkowym nie ma cyfry 9
Jeżeli zapis liczby całkowitej rozpoczyna się od znaków 0x
,
to interpreter Pythona przyjmuje,
że liczbę tę podano w systemie szesnastkowym.
Cyfry szesnastkowe przypisane liczbom naturalnym
od 0 do 15 oznaczane są symbolami: 0123456789abcdef,
przy czym dopuszczalne jest także użycie wielkich liter.
12 12 0x12 18 # tj. 1*16 + 2*1 0x1b3 435 # tj. 1*256 + 11*16 + 3*1; cyfrze b odpowiada wartość liczbowa 11
Jeżeli zapis liczby całkowitej rozpoczyna się od znaków 0b
,
to interpreter Pythona przyjmuje,
że liczbę tę podano w systemie dwójkowym.
W tym przypadku dozwolone jest użycie jedynie cyfr: 0 i 1.
11 12 0b11 3 # tj. 1*2 + 1*1 0b1011 11 # tj. 1*8 + 0*4 + 1*2 + 1*1
Twórcy Pythona 3 uznali, że niejednolitość opisanych wyżej reguł
określania stałych liczbowych jest wadą języka. Na dodatek, konwencja nakazująca
traktowanie zapisów rozpoczynających się zerem jako liczb w notacji ósemkowej
jest nieintuicyjna. Dlatego w Pythonie 3 konwencja ta została zmieniona.
Dla systemu ósemkowego wprowadzono notację 0o
,
analogiczną do notacji 0b
i 0x
.
Przy tym, dla uniknięcia nieporozumień co do użytej podstawy liczbowej,
stałe całkowitoliczbowe różne od zera nie nie mogą
być określane ciągami cyfr dziesiętnych rozpoczynającymi się cyfrą 0
.
Użycie takic hstałych generuje błąd składniowy.
(Na przykład ciąg znaków 012
, który w Pythonie 2
oznaczał liczbę 10, w Pythonie 3 jest niedozwolony jako stała liczbowa.
Legalne są natomiast zarówno 0o012
, jak 0o12
.)
Reguły te dotyczą wyłącznie stałych (literałów) umieszczanych w kodzie źródłowym.
Podczas czytania liczb z urządzeń znakowych (terminali, plików itp.)
dane tekstowe muszą być poddane konwersji na typy liczbowe;
w tym przypadku dopuszczalne są jedynie ciągi cyfr (choć niekoniecznie dziesiętnych)
niepoprzedzone sekwencją 0znak
wskazującą użytą podstawę systemu pozycyjnego.
Mogą one rozpoczynać się dowolną liczbą zer.
Trzy działania
a ^ b a | b a & b
określone dla liczb całkowitych oznaczają odpowiednio alternatywę wykluczającą (xor), alternatywę (or) oraz koniunkcję (and) cyfr dwójkowych na odpowiadających sobie pozycjach.
type(1) type(1L) 1+2+3 1+2L+3 2147483647+1 1+2*3+4 (1+2)*(3+4) 6+(5*(4+3))**2 2**3 10**2 10**20 long(1) int(10**20) 1/2 10 / 3 10 % 3 2**3**4 2**(3**4) (2**3)**4 123 0123 0x10**2 0xff + 1 0xab + 012 - 3
W Pythonie do reprezentowania liczb rzeczywistych
służy typ zmiennopozycyjny o nazwie float
.
float
)1.0, 1.5, -2.122, 123.44, 1.33E-5, -5.4333E+4
Część dziesiętna jest oddzielona od części całkowitej za pomocą znaku kropki.
W zapisie pojedynczej danej liczbowej mogą wystąpić jedynie: opcjonalnie znak + lub - na początku, liczba dziesiętna opisana ciągiem cyfr zawierającym co najwyżej jedną kropkę, po czym opcjonalnie litera E (lub e) z następującym po niej ciągiem cyfr, opcjonalnie poprzedzonym znakiem + lub -.
Dane typu float
są danymi zmiennopozycyjnymi
podwójnej precyzji wg terminologii IEEE.
Działania
a + b # dodawanie liczb a - b # odejmowanie liczb a * b # mnożenie liczb a / b # dzielenie liczb rzeczywistych daje wynik rzeczywisty a // b # dzielenie całkowite, z odrzuceniem części ułamkowej a % b # reszta z dzielenia a przez b a ** b # potęgowanie liczb
Priorytety operacji są w przypadku danych zmiennopozycyjnych takie same, jak w przypadku danych całkowitoliczbowych. Takie same są też reguły grupowania wyrażeń za pomocą nawiasów.
type(1.0) float(1) 1.0/2.0 8.0//3.0 2.0**3+1 (2.0**3)+1 2.0**(3+1) 2**(1/2) 2**(1/2.0) 2**0.5 (1-2**0.5) / (1+2**0.5) 1+2+3.0 10.0 / 3 10.0 // 3 10.0 % 3
Z modelu zmiennopozycyjnego wynika, że nie zawsze wynik obliczeń jest dokładny. Nie zawsze dana typu rzeczywistego jest tą liczbą, za którą ją zwykliśmy uważać:
1.0/2 0.5 1.0/10 0.10000000000000001 1.0/10 == 0.1 True 0.1 0.10000000000000001 0.10000000000000001 == 0.1 True
Przyczyny takiego zachowania zostały wyjaśnione w rozdziale 2.2. Pozornie paradoksalny wynik jest konsekwencją faktu, że liczba 0.1 nie ma dokładnej reprezentacji zmiennopozycyjnej w arytmetyce dwójkowej. Interpreter Pythona nie ukrywa tego faktu przed użytkownikiem, podczas gdy systemy użytkowe używają różnych metod, nieraz wyrafinowanych, dla przedstawienia danych w postaci zgodnej z potocznymi oczekiwaniami.
Wartość zmiennopozycyjna NaN (patrz podrozdział 2.2.2.)
jest reprezentowana w Pythonie jako nan
.
Nie jest to nazwa, tylko wartość. Z uwagi na fakt, że NaN
jest potrzebna tylko w sytuacjach wyjątkowych, nie ma możliwości
jej użycia w wyrażeniach jako stałej. Najprostszym sposobem
wygenerowania danej o wartości nan
jest konwersja
float('NaN')
; wartość tę da się oczywiście przypisać zmiennej:
a = float('NaN')
Wszelkie obliczenia numeryczne wykorzystujące wartość nan
prowadzą do wyników o wartości nan
.
Na dodatek wszelkie przyrównania i porównania danych liczbowych z nan
,
oraz wartości nan
z samą sobą, dają zawsze wynik negatywny:
n = float('NaN') n == 1.0 False n == n False n <= 1.0 False n >= 1.0 False n != 1.0 True n != n True
Dane tekstowe (typ str
) są ciągami znaków.
Wartości tekstów podajemy w ogranicznikach:
w pojedynczych apostrofach lub w cudzysłowach technicznych.
Napisy objęte ogranicznikami "…" lub '…' muszą mieścić się w jednym wierszu kodu źródłowego.
'xxx' 'xxx' "xxx" 'xxx' type('Ala') <type 'str'> type('123') <type 'str'>
Napisy objęte ogranicznikami """…""" lub '''…''' mogą rozciągać się na kilka wierszy kodu źródłowego.
"""napis wielowierszowy"""
Działania
a + b # łączenie napisów a i b a * b # zwielokrotnianie napisów; a jest napisem, b jest liczbą całkowitą nieujemną lub na odwrót
Znaki w napisach są numerowane. Pierwszy znak ma zawsze numer 0.
Pobieranie fragmentów napisów
napis[0] # pierwszy w kolejności element (znak) napisu napis[1] # drugi, itd. napis[-1] # ostatni napis[-2] # przedostatni, itd. napis[0:3] # fragment napisu obejmujący znaki od pierwszego do trzeciego napis[2:] # od trzeciego aż do końca napis[-2:] # dwa ostatnie znaki
Długość ciągu znaków obliczamy za pomocą funkcji len()
len(napis)
Operacją blisko związaną z pobieraniem fragmentu tekstu jest sprawdzanie,
czy dany znak lub tekst jest fragmentem innego tekstu. W Pythonie
da się to sprawdzić korzystając z operatora przynależności in
:
'a' in 'Ala ma asa' True 'z' in 'Ala ma asa' False
Można w ten sposób badać nie tylko pojedyncze znaki, ale dowolne teksty:
'Ala' in 'Ala ma asa' True 'As' in 'Ala ma asa' False
Tym sposobem nie dowiemy się, ile razy ani na której pozycji dany tekst występuje w dłuższym tekście.
Operator in
odnosi się zawsze do przynależności,
choć niekoniecznie do danych typu tekstowego.
Istnieje także operator not in
.
Za jego pomocą sprawdza się, czy dany element
nie należy do danego zbioru.
Znak odwrotnego ukośnika jest wewnątrz napisów znakiem sterującym. Od niego rozpoczynają się nazwy ważnych znaków specjalnych, m.in.:
'\n' # znak nowego wiersza (LF) '\t' # znak tabulacji # Ooo! jak w wyrażeniach regularnych! '\r' # znak powrotu do początku wiersza (CR) # Sekwencja '\r\n' (CR+LF) jest używana na końcach wierszy w plikach tekstowych w systemach Windows '\\' # znak ukośnika \
Znak sterujący przydaje się także w sytuacji, kiedy wewnątrz napisu ograniczonego cudzysłowami chcemy umieścić taki sam symbol cudzysłowu:
"'" '\'' # znak apostrofu ' '"' "\"" # znak cudzysłowu "
Kolejne zastosowanie symbolu sterującego wiąże się z kodami znaków UNICODE. Będzie o tym mowa w podrozdziale 6.1. Do tego czasu założymy, że zamierzamy używać w napisach wyłącznie podstawowych znaków ASCII, tj. cyfr arabskich, liter łacińskich i znaków przestankowych.
'Ala' + ' ' + 'ma' + ' '+ 'kot' + 'a.' 'Ala ma kota.' 2*'Ala' + ' ma ' + 2*('kot'+'a') + '.' 'AlaAla ma kotakota.' 'Komputerowe wspomaganie projektowania'[0] 'K' 'Komputerowe wspomaganie projektowania'[0:10] 'Komputerow' 'Komputerowe wspomaganie projektowania'[-1] 'a' 'Komputerowe wspomaganie projektowania'[-8:] 'ktowania' """Komputerowe wspomaganie projektowania""" 'Komputerowe\nwspomaganie\nprojektowania' "Komputerowe\nwspomaganie\nprojektowania" 'Komputerowe\nwspomaganie\nprojektowania' len('Ala i As') 8 len('Ala\ti\tAs') 8 len('Ala\ti\tAs\n') 9 'przedmiot \'Komputerowe wspomaganie projektowania\'' "przedmiot 'Komputerowe wspomaganie projektowania'"
Dla informacji, że instrukcja lub wyrażenie nie zostało zakończone,
zgłoszenie interpretera przybiera postać ...
zamiast
>>>
.
Operacja formatowania napisów bywa użyteczna
przy generowaniu raportów wynikowych. Służy do niej operator
%
:
szablon % arg # podstawianie sformatowanych wartości umieszczonych w arg do wzorca szablon
Wynik formatowania jest zawsze daną typu tekstowego.
Napis wzorcowy szablon
może zawierać dowolny tekst.
Miejsca podstawienia argumentów oznacza się w nim za pomocą kodów:
%s
dla argumentu tekstowego,
%d
dla argumentu będącego liczbą całkowitą,
%f
dla argumentu będącego liczbą zmiennopozycyjną.
Kody argumentów można uzupełniać dyrektywami o sposobie ich przedstawienia,
tj. liczbie znaków i dokładności liczb. Dyrektywa %%
oznacza
znak procenta.
Wartość arg
może być albo pojedynczym argumentem
typu logicznego, tekstowego lub liczbowego, albo uporządkowanym ciągiem
takich argumentów. W przypadku, kiedy typ dostarczonego argumentu jest inny,
niż opisany przez dyrektywę formatowania, dokonywana jest konwersja.
W przypadku formatowania pojedynczej danej tekstowej
operatora %
można użyć następująco
(napis zostanie po prostu wstawiony w miejsce symbolu %s
):
'miasto %s' 'miasto %s' 'miasto %s' % 'Warszawa' 'miasto Warszawa' 'miasto %s' % 'Kraków' 'miasto Kraków'
W przykładzie niżej napisy zostaną przedstawione przy użyciu co najmniej 20 znaków.
'miasto %20s' 'miasto %20s' 'miasto %20s' % 'Warszawa' 'miasto Warszawa' 'miasto %20s' % 'Wrocław' 'miasto Wrocław' 'miasto %20s' % 'Zielona Góra' 'miasto Zielona Góra'
W przypadku formatowania pojedynczej danej liczbowej
operatora %
używa się następująco:
'%f' % 123.45' # przedstawienie domyślne '123.450000' '%.3f' % 123.45' # 3 cyfry dziesiętne '123.450' '%10.4f' % 123.45' # co najmniej 10 znaków, w tym 4 cyfry dziesiętne ' 123.4500' '%20.12f' % 123.45' # co najmniej 20 znaków, w tym 12 cyfr dziesiętnych ' 123.450000000000'
Dalsze szczegóły dotyczące operacji formatowania, zwłaszcza dotyczące przypadku większej liczby argumentów, podamy w podrozdziale 6.6, po wprowadzeniu typów danych umożliwiających przechowywanie ciągów wartości.
Do zarządzania wartościami logicznymi służy w Pythonie
typ bool
zawierający dwie wartości:
True
False
type(True) type(False)
and
, or
, not
— operatory logiczne
obliczające koniunkcję, alternatywę i negację wartości dostarczonych wyrażeń.
True or False not True
Skąd się biorą dane logiczne? często z przyrównań innych danych
a == b # sprawdzenie, czy dwie wartości są równe a != b # sprawdzenie, czy dwie wartości są różne a <> b # sprawdzenie, czy dwie wartości są różne
W starszych wersjach Pythona notacje
a != b
i a <> b
można stosować zamiennie. W Pythonie 3 operator <>
został usunięty z języka.
albo z ich porównań
a > b a < b a >= b a <= b
W Pythonie typy porównywanych wartości nie muszą być zgodne, ale jeżeli się różnią, to trzeba umieć zinterpretować wynik.
1+1 == 2 # przyrównanie wyrażeń liczbowych True 10 == 10.0 # przyrównanie liczb różnych typów; automatyczna konwersja True 10 == '10' # przyrównanie liczby i tekstu; zawsze False False 10 > 2 # porównanie liczb True 10 > 2.0 # porównanie liczb różnych typów True '10' > '2' # porównanie napisów, obowiązuje porządek słownikowy False '10' > 2 # porównanie danych różnych typów -- co to znaczy? True '20' > 20 # na pewno co innego, niż byśmy chcieli... tylko co? True '20' > 10 True '10' > 20 True 10 > '20' False 20 > '10' False
W Pythonie 2 wynik porównania danych mających niezgodne typy zależy od porównania nazw tych typów. Zatem nigdy nie jest to wartość sensowna z punktu widzenia „zwykłego użytkownika”.
W Pythonie 3 próby porównywania danych mających niezgodne typy prowadzą do wygenerowania błędu.
W jaki sposób przyrównywać bądź porównywać wiele wartości naraz? Czy to się w ogóle da zrobić?
Na przykład zdanie testujące przynależność wartości x do przedziału [a, b) w klasycznym rachunku zdań ma postać (a ≤ x) ∧ (x < b). W notacji matematycznej bywa ono wyrażane krócej jako (a ≤ x < b). Powstaje pytanie: czy notacja ta jest dopuszczalna w językach programowania?
W Pythonie — tak. Oba zapisy
(a <= x) and (x < b) a <= x < b
wyrażają w zasadzie ten sam warunek (istnieją sytuacje, w których ostateczne efekty spowodowane użyciem tych wyrażeń są odmienne, jednak nie dotyczy to przypadków, kiedy a, b i x są stałymi, zmiennymi, ani wynikami działań arytmetycznych na stałych i zmiennych).
W innych językach — niekoniecznie, ale na ogół nie. Nieprzemyślane użycie skrótowej notacji bywa powodem błędów rzeczowych.
W językach, w których operatory przyrównań i porównań są konsekwentnie traktowane jak operatory dwuargumentowe, przyjęta zostanie następująca interpretacja:
Nie ma ona nic wspólnego z pierwotnym sensem warunku. Jednak jeżeli środowisko wykonawcze dokonuje konwersji wartości logicznych na dane liczbowe (a jest to norma w wielu językach programowania), to odpowiedź — mimo że bezsensowna z punktu widzenia użytkownika — zostanie udzielona.
Analogiczna składnia jest dozwolona także w przypadku innych operatorów. Na przykład wyrażenia
a == b == c a != b != c a != b <= c a < c != b < d
są równoważne odpowiednio wyrażeniom
(a == b) and (b == c) (a != b) and (b != c) (a != b) and (b <= c) (a < c) and (c != b) and (b < d)
czyli koniunkcji zdań powstałych przez rozdzielenie operatorów.
Chcąc skłonić Pythona do innej kolejności interpretacji,
powinniśmy użyć nawiasów, np. a == (b == c)
,
(a < c) != (b < d)
, itp.
Szczególnym sposobem przyrównywania jest sprawdzenie, czy dwa obiekty
są tożsame, czyli identyczne. Służy do tego operator is
oraz blisko z nim związany is not
.
a == b # sprawdzenie, czy dwie wartości są równe a is b # sprawdzenie, czy wartości a i b są reprezentowane przez ten sam obiekt a is not b # sprawdzenie, czy wartości a i b są reprezentowane przez dwa różne obiekty
Tożsamość oznacza znacznie więcej, niż równość; szczegóły objaśnimy w podrozdziale 10.1.3.
Operatory is
i is not
odnoszą się do sposobu przechowywania danych w pamięci.
Operatorami zwracającymi wartości logiczne są także operatory przynależności: in
i blisko z nim związany not in
.
Była o nich mowa w podrozdziale 5.3.3. przy okazji omawiania
danych tekstowych; powrócimy do nich jeszcze raz w podrozdziałach rozdziału 6.
poświęconych listom,
słownikom
i zbiorom.
a in b # sprawdzenie, czy wartość a jest elementem b a not in b # sprawdzenie, czy wartość a nie jest elementem b
Wartości wyrażeń a not in b
(a nie jest elementem b
)
oraz not a in b
(nieprawda, że a jest elementem b
)
są jednakowe.
Python ma wbudowany typ liczb zespolonych (typ complex
).
W notacji zespolonej część urojoną oznacza się za pomocą
wartości liczbowej z przyrostkiem j
.
Współczynnika liczbowego nie wolno pominąć.
Do wykonywania działań arytmetycznych na danych zespolonych
służą operatory + - * / **
znane z działań na liczbach zmiennopozycyjnych.
1j 1j 1j**2 (-1+0j) (1j - 2.5)*2.0 - 0.5j (-5.0+1.5j)
Dana zespolona o zerowej części urojonej nie jest daną rzeczywistą.
type(-1+0j) <type 'complex'> (-1+0j) == -1.0 True
Do wyłuskania części rzeczywistej i części urojonej służą odpowiednio
operatory real
i imag
(notacja obiektowa):
(-1+2j).real -1.0 (-1+2j).imag 2.0
Zwracają one wartości typu zmiennopozycyjnego float
,
nawet jeśli ich części ułamkowe są równe zeru.
W Pythonie możliwe jest również wykonywanie obliczeń
na liczbach dziesiętnych (Decimal
)
oraz na liczbach wymiernych (Fraction
)
z utrzymaniem pełnej dokładności wyników.
Niniejsze opracowanie nie omawia odpowiednich typów danych ani sposobu ich użycia.
Do obsługi danych dotyczących dat, terminów i odstępów czasu
służy w Pythonie moduł datetime
.
Umożliwia on większość typowych operacji na datach.
Wartości dat są przechowywane jako dane typu złożonego.
import datetime datetime.date.today() # bieżąca data datetime.date(2011, 2, 22) str(datetime.date.today()) # jako napis '2011-02-22' datetime.date(2011,01,01) # wskazana data datetime.date(2011, 1, 1) datetime.date.today() - datetime.date(2011,01,01) # czas między dwiema datami datetime.timedelta(52) datetime.date.today().year # rok z danej daty 2011 datetime.date.today().month # miesiąc z danej daty 2 datetime.date.today().day # dzień miesiąca z danej daty 22 datetime.date.today().weekday() # dzień tygodnia z danej daty 1 datetime.date(2010, 12,30) + datetime.timedelta(10) # data plus czas trwania w dniach datetime.date(2011, 1, 9)
Dokładność reprezentacji dat jest ograniczona do dni kalendarzowych. Bardziej precyzyjne obliczenia dotyczące czasu
przeprowadza się w podobny sposób za pomocą struktur udostępnianych przez moduł datetime
,
m.in. datetime.time
(czas zegarowy w obrębie doby), datetime.timedelta
(czas trwania,
czyli przedziały czasu) oraz datetime.datetime
(data + czas zegarowy).
None
None
— nic.
Bardzo ważna wartość używana do wyrażania braku sensownej wartości, nieistnienia danej, itp.
W Pythonie 3 słowo None
jest słowem kluczowym.
None bool(None) str(None) int(None)
Łatwo sprawdzić, że wartość None
należy do typu danych o nazwie NoneType
:
type(None) <type 'NoneType'>
Do przedstawiania brakujących danych liczbowych lepiej od None
nadaje się wartość nan
. W przeciwieństwie do None
,
nan
jest wartością typu zmiennopozycyjnego, więc jej użycie
w rachunkach nie powoduje błędu i zawsze zwraca wynik nan
.
Najprostszym sposobem uzyskania wartości nan
jest wyrażenie
float('NaN')
.
Ciekawostką jest, że same typy danych są wartościami typu type
.
type(int) <type 'type'> type(float) <type 'type'> type(type) <type 'type'> type(1.0) == int False type(1.0) == float True
Sprawdzenie niektórych typów prowadzi do trudności. Na przykład
type(None) <type 'NoneType'> type(NoneType) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'NoneType' is not defined
Błąd wynika z faktu, że typ NoneType
i jego właściwości domyślnie nie są udostępniane użytkownikowi
za pomocą nazwanego obiektu. Mimo to możemy sprawdzić:
type(type(None)) <type 'type'>
Konwersja jest to zamiana wartości pewnego typu na odpowiadającą jej wartość innego typu. W Pythonie konwersję wymusza nazwa typu z wartością umieszczoną w nawiasie jako argument. Nie każda konwersja jest wykonalna.
str(1.0) str(True) float(1) int(2.5) float('1.23') int('2.5') bool(1) bool(2) bool('1') bool('a') ...
Przy konwersji do typu logicznego, wartości liczbowe 0
i 0.0
,
wartość tekstowa ""
(pusty napis), wartość None
,
a także, co się okaże istotne w przyszłości, puste listy [ ]
i ( )
,
są zamieniane na wartość logiczną False
.
Wartościom liczbowym różnym od zera, niepustym napisom i niepustym listom
konwersja taka przypisuje wartość logiczną True
.
Właściwości te są bardzo często pomocne podczas konstruowania i sprawdzania warunków.
bool(0) False bool(1) True bool(2) True bool("") False bool("Ala") True bool("As") True
Wynika stąd, że konwersja, jako operacja nieodwracalna, może prowadzić do utraty informacji. Oto przykłady:
bool(1) True bool(2) True True == 1 True True == 2 False
Kiedy konwersja może wprawić nas w zakłopotanie? Wtedy, kiedy jej nie rozumiemy do końca. Na przykład:
str(True) 'True' True == 'True' # typy bool i str nie są zgodne, wynik zawsze False False True == 1 # niejawnie dokonuje się konwersja typu bool na int True int(True) # eksperyment potwierdzający powyższe przypuszczenie 1 str(True) == str(1) # obie strony przyrównania są tego samego typu str, przyrównujemy napisy 'True' i '1' False bool('True') == bool('False') # każdy niepusty napis jest konwertowany na True True
Umiemy już używać sesji Pythona do doraźnego obliczania wartości wyrażeń. Rozumiemy też, od czego zależy typ otrzymywanego wyniku. Czas poszerzyć możliwości naszego kalkulatora.
…a raczej z dowolną ilością pamięci.
Do obszarów pamięci przechowujących wartości będziemy się odwoływać za pomocą zmiennych. Zmienne są rozpoznawane za pomocą nazw, nadawanych im przez użytkownika.
Wygodnie jest myśleć o zmiennych jak o pojemnikach umożliwiających przechowywanie wartości. W przyszłości okaże się, że analogia ta nie jest zupełnie ścisła, i że w Pythonie zmienne są raczej „etykietami” takich pojemników.
Nową zmienną inicjujemy, zapamiętując pewną wartość pod nowo nadaną nazwą:
nazwa = wartość # przypisuje wartość zmiennej o podanej nazwie
Nazwa winna być słowem składającym się wyłącznie z liter łacińskich, cyfr i znaku podkreślenia, przy czym nie może rozpoczynać się cyfrą. Nazwa nie może też być słowem kluczowym języka. Wynika z tego, że nazwa nie może zawierać spacji (podobne reguły rządzą nazwami obiektów w wielu innych środowiskach i warto ich przestrzegać, nawet jeśli w danej sytuacji nie są koniecznością). Wielkie i małe litery są w nazwach rozróżniane.
Poniższe nazwy nie są równoważne:
dlugoscwektora dlugosc_wektora dlugoscWektora DlugoscWektora
choć wszystkie są równie sensownymi kandydat(k)ami na nazwę pewnego obiektu.
Poniższe nazwy są nielegalne (czyli de facto nie mogą być nazwami):
długość wektora # bo zawiera spacje i litery spoza alfabetu łacińskiego długośćWektora # bo zawiera litery spoza alfabetu łacińskiego dlugosc wektora # bo zawiera spacje 2dlugoscwektora # bo rozpoczyna się od cyfry while # bo jest słowem kluczowym
Próba użycia niezadeklarowanej nazwy w obliczanym wyrażeniu jest nielegalna i prowadzi do błędu.
wartosc Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'wartosc' is not defined wartosc = 123.45 wartosc 123.45 wartosc = wartocs + 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'wartocs' is not defined
Jeżeli zmienna o wskazanej nazwie już istnieje, to podczas przypisania zostanie jej nadana nowa wartość.
ktos = 'Ala' cos = 'kot' ktos + ' ma ' + cos+'a.' 'Ala ma kota.' zdanie = ktos + ' ma ' + cos+'a.' zdanie 'Ala ma kota.' ktos = 'Zuzia' ktos + ' ma ' + cos+'a.' 'Zuzia ma kota.' cos = 'zając' ktos + ' ma ' + cos+'a.' 'Zuzia ma zająca.' cos == 'kot' False cos = 'pies' ktos + ' ma ' + cos+'a.' 'Zuzia ma piesa.' zdanie 'Ala ma kota.'
Zmienna sama z siebie nie ma określonego typu. Typ ma przechowywana w niej wartość (trochę podobnie, jak komórka w arkuszu kalkulacyjnym). Nic nie stoi na przeszkodzie, by nowa wartość nadana zmiennej była innego typu, niż wartość przechowywana poprzednio od tą samą nazwą.
a = 'Ala' type(a) <type 'str'> a = 123.55 type(a) <type 'float'> a = a == 'Ala' type(a) <type 'bool'> a = int(a) type(a) <type 'int'>
Związek między wartościami i zmiennymi jest głębszy, niż się może wydawać na pierwszy rzut oka. Wiedzę na ten temat usystematyzujemy w podrozdziale 10.1.3.
Modyfikując wartość zmiennej możemy korzystać z jej poprzedniej wartości.
a = 2 a = a + 2 a = a * 3.0 a 12.0
Służą do tego specjalne warianty operatora przypisania:
+= -= *= /=
.
Wykorzystamy je do zsumowania ciągu liczb:
a = 0.0 a += 3 a += 2.5 a += 3.12 a += -0.33 a 8.2900000000000009 # zamienimy wartość podaną w calach na milimetry a *= 25.4 a 210.566
To samo działa także na danych tekstowych
a = 'Ala' a += ' ' a += 'i' a += ' ' a += 'As' a 'Ala i As'
Zmiana fragmentu istniejącego napisu nie jest możliwa.
a = 'Ala i As' a[0] 'A' a[0] = 'O' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment
Zamiast tego trzeba „zbudować” napis od nowa. Warto przy tym korzystać z istniejących fragmentów:
a = 'O' + a[1:] a 'Ola i As' b = a[0:6] + 'O' + a[-1:] + 'a' b 'Ola i Osa'
Python dopuszcza także rozszerzone warianty instrukcji przypisania. Instrukcja
a = b = wartość
przypisuje dwóm zmiennym (lub dowolnej większej ich liczbie) tę samą wartość. W wyniku takiej operacji zmienne nie tylko otrzymują tę samą wartość, ale będą reprezentować ten sam obiekt (więcej na ten temat powiemy w podrozdziale 10.1.3.).
Kolejny wariant instrukcji przypisania
a, b = wartość1, wartość2
przypisuje pierwszą wartość pierwszej zmiennej, drugą — drugiej, itd.
Wszystkie wyrażenia z prawej strony są obliczane przed wykonaniem przypisań,
więc jeżeli zmienne a
lub b
występują w obliczanych wyrażeniach, to używane są w nich ich stare wartości.
Dlatego w efekcie poniższej instrukcji:
a, b = b, a
zmienne a
i b
zamieniają się wartościami.
Takie zachowanie jest charakterystyczne dla Pythona.
W językach programowania nie dopuszczających „równoczesnych”
przypisań — a są one w większości — zamianę wartości zmiennych
a
i b
realizuje się przy wykorzystaniu zmiennej pomocniczej:
# niech a ma wartość 1, b ma wartość 2 # a: 1, b: 2 p = a # stan po wykonaniu -- a: 1, b: 2, p: 1 a = b # stan po wykonaniu -- a: 2, b: 2, p: 1 b = p # stan po wykonaniu -- a: 2, b: 1, p: 1 # możemy usunąć zmienną pomocniczą p
Bez użycia pomocniczej zmiennej p
przypisanie a = b
nieodwracalnie usunęłoby wartość początkowo przechowywaną w zmiennej
a
:
# niech a ma wartość 1, b ma wartość 2 # a: 1, b: 2 a = b # stan po wykonaniu -- a: 2, b: 2 b = a # stan po wykonaniu -- a: 2, b: 2
W tej sytuacji instrukcja b = a
nie miałaby
żadnego realnego znaczenia.
Operacją odwrotną do ustanowienia zmiennej jest jej usunięcie. Nie wnikając w szczegóły możemy stwierdzić, że usunięcie zmiennej skutkuje zwolnieniem zajmowanej przez nią pamięci. Po usunięciu zmiennej operowanie na niej nie jest możliwe (choć w razie potrzeby można powołać nową zmienną o tej samej nazwie).
Zmienne usuwa się za pomocą instrukcji del nazwa_zmiennej
.
a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined a = 123 a 123 del a a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined
del
jest
słowem kluczowym Pythona.
Inną metodą ograniczania zakresu istnienia zmiennych jest deklarowanie ich wewnątrz podprogramu. Zmienna zostanie usunięta z chwilą zakończenia wykonywania podprogramu. Więcej informacji znajdziesz w podrozdziale 7.6.
Funkcja definiuje pewien tok obliczania wartości wynikowej. Funkcja posiada nazwę, której należy użyć w celu obliczenia wyniku.
Wynik obliczeń zależy od podanych wartości argumentów. Liczba argumentów oraz ich znaczenie są określone osobno dla każdej funkcji.
W Pythonie dostępnych jest kilkadziesiąt predefiniowanych funkcji. Są one wymienione w dokumentacji (w wersji 3.x lista funkcji standardowych jest nieco inna).
Przykłady użycia funkcji:
abs(-4.5) # oblicza wartość bezwzględną round(4.5) # zaokrąglenie do wartości całkowitej (wynik jest typu zmiennopozycyjnego) round(4.55, 1) # zaokrąglenie do wartości z jedną cyfrą dziesiętną pow(2, 3) # to samo co 2**3 max(2, 3, -1) # zwraca największy z argumentów len('Ala i As') # oblicza liczbę znaków w tekście input('Podaj liczbę ') # odczytuje wpis użytkownika z wejścia chr(128) # generuje znak o podanym kodzie liczbowym
Konwersja typów nie jest funkcją, ale używa się jej podobnie jak funkcji:
int(4.5) str(1234) float('123.45')
Wywołanie funkcji jest wyrażeniem, zatem ma wartość. Można go więc użyć w wyrażeniach złożonych, albo zapamiętać jego wynik w zmiennej:
abs(pow(a, 2) - pow(b, 2)) ab = pow(pow(a,2.0) + pow(b,2.0), 0.5) sameiksy = len('Ala i As')*'x' wzrost = 0.01*float(input('Twój wzrost [cm] = ')) m = max(a, b, c, d)
Czym jest funkcja w programie?
type(abs) type(len) type(input)
Co robi dana funkcja?
help(abs) help(len) help(input)
Inne funkcje (pierwiastek? logarytmy? funkcje trygonometryczne?) — jeżeli ich nie ma…
x = 0 y = sin(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'sin' is not defined
… to trzeba albo skądś je wziąć, albo je sobie napisać.
Na szczęście brać jest skąd (patrz następny podrozdział 5.4.3), a i pisać własne wkrótce się nauczymy (patrz podrozdział 7.6).
Co to jest moduł? jest to plik zawierający deklaracje przeznaczone do wykorzystania w programach Pythona. W najprostszym przypadku moduł jest zwykłym plikiem źródłowym Pythona, choć bywa też inaczej.
Wczytanie modułu w najprostszym przypadku następuje za pośrednictwem
dyrektywy import
:
import nazwa_modułu
Pozwala to użytkownikowi korzystać z obiektów zadeklarowanych w module.
Przy opisanym wyżej sposobie wczytywania modułu zdefiniowane w nim obiekty
noszą nazwy postaci nazwa_modułu.nazwa_obiektu
.
Inne sposoby wczytywania modułów, oparte na wariancie składni polecenia
import
z wykorzystaniem słów kluczowych from
oraz as
, umożliwiają dostęp do obiektów zdefiniowanych
w module bez poprzedzania ich nazw nazwą modułu, lub z poprzedzeniem ich
dowolnie ustaloną nazwą.
Składnia
from nazwa_modułu import *
powoduje wczytanie wszystkich elementów ze wskazanego modułu, przy czym ich nazw w wywołaniach nie będzie trzeba poprzedzać nazwą modułu.
Składnia
import nazwa_modułu as nazwa
powoduje wczytanie wskazanego modułu, i udostępnienie go w programie pod nazwą inną niż domyślna.
Ważnym modułem jest math
, wchodzący w skład każdej instalacji
Pythona. Zawiera on deklaracje wielu przydatnych funkcji matematycznych.
import math math.sqrt(5.0) 2.2360679774997898 math.pi 3.1415926535897931 math.sin(math.pi/2) 1.0 math.log(1.0) 0.0 math.e 2.7182818284590451 math.log(math.e) 1.0
Python posiada bardzo wiele modułów standardowych, i nieograniczoną liczbę modułów dodatkowych, wymagających zainstalowania. Oprócz tego użytkownik może tworzyć własne moduły.
Moduły są dla programu takimi samymi obiektami, jak wszystkie inne (np. zmienne). Możemy się o tym przekonać, sprawdzając typ wczytanego modułu
type(math) <type 'module'>
albo listując jego zawartość:
dir(math) ['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
Dla usunięcia zaimportowanego modułu z pamięci programu wystarczy
użyć instrukcji del
, np.
del math
Operacja taka nie czyni żadnej krzywdy plikowi, z którego moduł został załadowany.
Operatory działań, zmienne reprezentujące pamięć, funkcje, … Taki repertuar środków sprawia, że interpreter Pythona jest bardzo rozbudowanym kalkulatorem.
Jednak do programowania potrzebna jest jeszcze komunikacja z otoczeniem. Dobra praktyka wymaga, by program pobierał dane z zewnątrz i udostępniał wyniki poza swoim środowiskiem. Metod na osiągnięcie tego celu jest sporo. W bieżącym paragrafie omawiamy klasyczne metody wbudowane w język, współpracujące ze standardowym mechanizmem wejścia i wyjścia dostarczanym przez system operacyjny.
Instrukcja print(wyrażenie)
wypisuje wartość wyrażenia na konsoli wynikowej. Wyrażeń może
być więcej, należy je wtedy oddzielać przecinkami.
a = 'Ala' b = 'As' print(a + ' i ' + b) Ala i As print(a, b) Ala As print(1.0) 1.0 print(1+2+3+4, 1*2*3*4) 10 24
Domyślnie funkcja print
wstawia znak nowego wiersza (Enter)
po ostatniej wydrukowanej frazie. Przekazanie jej dodatkowego argumentu end = ''
sprawi, że znak nowego wiersza zostanie pominięty.
Zwróćmy uwagę, że funkcja print
w pewien sposób formatuje wydruk:
a = 0.1 a 0.10000000000000001 print(a) 0.1
print
zastępuje w tekstach kody znaków specjalnych ich znaczeniem,
np. '\t'
zostaje zastąpione znakiem tabulacji,
a '\n'
— znakiem końca wiersza.
podobnie traktowane są kody znaków spoza alfabetu ASCII.a = 'Ala' b = 'As' print(a + ' i ' + b) Ala i As print(a + '\ti\t' + b) Ala i As print(a + '\ni\n' + b) Ala i As
print
jest
słowem kluczowym Pythona do wersji 2.x włącznie.
Nawiasy wokół drukowanych wyrażeń nie były wymagane przez składnię.
W Pythonie 3 słowo kluczowe print
nie istnieje.
Została za to wprowadzona funkcja o tej samej nazwie. Zatem wyrażenia
przeznaczone do wydrukowania za pomocą instrukcji print
trzeba przekazywać w nawiasach:
print(wyrażenie) print(wyrażenie1, wyrażenie2)
Najprostszym sposobem pobrania przez program wartości zewnętrznej
jest użycie funkcji input()
.
Wynik przekazywany przez funkcję input()
jest zawsze tekstem.
W Pythonie 2 istniała funkcja raw_input()
, która
zachowywała się się tak, jak funkcja input()
znana z wersji 3.
Natomiast funkcja o nazwie input()
interpretowała tekst wprowadzony przez użytkownika,
a typ wartości wynikowej był ustalany w czasie tej interpretacji.
Dawało to możliwość niekontrolowanego wykorzystania działania przez operatora programu
i stało się bezpośrednią przyczyną wprowadzenia zmiany.
Wartość wpisaną przez użytkownika zazwyczaj chcemy gdzieś zapamiętać.
nazwa = input() # pobiera tekst od użytkownika i przypisuje go obiektowi nazwa
Jak argument funkcji input()
można podać dowolny tekst. Zostanie on przedstawiony użytkownikowi jako
komunikat zachęcający do wpisania wartości.
nazwa = input(komunikat) # to samo co input(), tylko przed pobraniem tekstu przekazuje komunikat dla użytkownika
x = input('Ile masz lat? ') Ile masz lat? 20 print('Wiem, że masz', x, 'lat') Wiem, że masz 20 lat x = input('Jak masz na imię? ') Jak masz na imię? Marcin print('Wiem, że masz na imię', x) Wiem, że masz na imię Marcin
Funkcja dir(obiekt)
pokazuje listę właściwości obiektu, np.
dir(math) dir('ala') dir(1)
Funkcja type(obiekt)
informuje o typie obiektu, np.
type(1) type('Ala ma Asa') type(max) type(math) type(math.pi)
Funkcja help(obiekt)
udostępnia podstawową dokumentację obiektu, np.
help() help(math) help(math.sin) help(abs)
Program źródłowy Pythona jest ciągiem poleceń zapisanych w pliku tekstowym po jednym poleceniu w każdym wierszu.
instrukcja instrukcja instrukcja instrukcja
Dopuszczalne jest także oddzielanie średnikami instrukcji zapisanych w jednym wierszu.
instrukcja; instrukcja instrukcja; instrukcja instrukcja
Zapisany tym sposobem ciąg instrukcji tworzy blok. W ramach jednego bloku instrukcje są wykonywane po kolei.
Jak zobaczymy w następnych rozdziałach, w Pythonie możliwe jest zagnieżdżanie bloków instrukcji. Jest ono wykorzystywane przy sterowaniu przebiegiem programu. Podział na bloki następuje za pomocą głębokości wcięć wierszy kodu źródłowego.
Do robienia wcięć mogą służyć znaki spacji lub znaki tabulacji, jednak nie należy ich mieszać ze sobą. Głębokości wcięć są dowolne, ale muszą być takie same w obrębie jednego bloku. Na razie po prostu piszmy instrukcje jedna pod drugą, unikając białych znaków na początku wiersza.
Używanie znaków spacji i tabulacji w jednym pliku jest zawsze nieeleganckie. Pociąga za sobą również niebezpieczeństwo błędnej interpretacji, gdyż różne edytory mogą przedstawiać tabulator za pomocą odmiennych głębokości skoku. Dlatego w Pythonie 3 wymaganie konsekwentnego stosowania tylko jednego z tych znaków zostało podniesione do rangi reguły składniowej.
Jeżeli instrukcja jest na tyle długa, że warto ją podzielić na kilka wierszy
dla zachowania czytelności, to wstawiamy symbol \
na końcu wiersza
dla oznaczenia, że instrukcja jeszcze się nie zakończyła.
# podział długiej instrukcji na wiersze zwiększa czytelność kodu ab = math.sqrt( (a[0] - b[0])**2 + \ (a[1] - b[1])**2 )
W takim przypadku wcięcie drugiego i następnych wierszy nie jest istotne.
Nie ma znaczenia, jakim edytorem się posłużymy podczas zapisywania
poleceń; ważny jest jedynie znakowy format zapisu.
Dobrym zwyczajem jest nadawanie plikowi źródłowemu
nazwy z rozszerzeniem py
.
Przy interaktywnym korzystaniu z konsoli Pythona
nie było widać wielu korzyści z funkcji print
.
Zbliżony skutek (nie licząc interpretacji znaków specjalnych)
dało się uzyskać wpisując wyrażenie bezpośrednio przy znaku zgłoszenia:
a = 'Ala' b = 'As' a + ' i ' + b Ala i As print(a + ' i ' + b) Ala i As a + '\ti\t' + b Ala\ti\tAs print(a + '\ti\t' + b) Ala i As
W trakcie interpretacji pliku źródłowego jest inaczej. Wpisywane wyrażenia są co prawda obliczane, ale nie są nigdzie drukowane; ich wartość nie jest też nigdzie zapamiętywana.
Żeby się o tym przekonać, zróbmy prosty eksperyment. Za pomocą dowolnego nieformatującego edytora utwórzmy plik tekstowy o następującej zawartości:
a = 'Ala' b = 'As' a + ' i ' + b
i zapiszmy go pod nazwą proba1.py
.
Po uruchomieniu polecenia
c:\Users\Ja\testy> python proba1.py
nie dostaniemy od interpretera żadnej informacji wynikowej.
Tymczasem funkcja print
, tak samo jak w trybie interaktywnym,
przesyła dane do standardowego pliku wynikowego. W konsekwencji
pojawiają się one na urządzeniu wyjściowym, np. na terminalu systemowym
lub w oknie środowiska programistycznego przeznaczonym do prezentacji
danych wynikowych.
Wykonajmy drugie doświadczenie: poniższy tekst
a = 'Ala' b = 'As' print(a + ' i ' + b)
zapiszmy w pliku proba2.py
.
Po uruchomienia programu otrzymamy na urządzeniu wyjściowym wydruk:
c:\Users\Ja\testy> python proba2.py
Ala i As
c:\Users\Ja\testy> python import nazwa
Uruchamianie programu tą metodą jest szczególnym przypadkiem importowania modułu.
Pisząc w przykładach polecenie systemowe python
zakładamy,
że system czytelnika został skonfigurowany zgodnie z zaleceniami wymienionymi
w podrozdziale 5.1.6. poświęconemu instalacji oprogramowania.
Dociekliwi zauważą, że podczas importowania modułu
z pliku py
następuje jego kompilacja.
Jej wynikiem jest plik binarny o rozszerzeniu pyc
(‘Python Compiled’).
Taki plik zawiera cały kod programu w postaci binarnej.
Można go uruchamiać analogicznymi sposobami, jak kod źródłowy,
bez konieczności posiadania tego ostatniego.
Ta metoda uruchamiania wywołuje z poziomu powłoki systemowej interpreter języka Python z nazwą programu jako argumentem. Możliwe jest również użycie nazwy programu źródłowego jako polecenia.
W systemach Windows (cmd
, powershell
)
c:\Users\Ja\testy> c:\python26\python nazwa.py
W przypadku, kiedy kartoteka w której zainstalowano Pythona jest wpisana na listę ścieżek
poszukiwania programów (PATH
; patrz podrozdział 5.1. —
nie dzieje się to podczas domyślnej instalacji), wystarczy polecenie postaci
c:\Users\Ja\testy> python nazwa.py
Natomiast wykorzystanie rozszerzonej składni interpretera systemowego, biorącej pod uwagę zarejestrowane w systemie powiązania rozszerzeń nazw plików z obsługującą aplikacją, pozwala uruchamiać program poleceniem postaci
c:\Users\Ja\testy> nazwa.py
W przypadku, kiedy w konfiguracji systemu rozszerzenie nazwy .py
zostało zadeklarowane jako wykonywalne, można je pominąć:
c:\Users\Ja\testy> nazwa
W systemach uniksowych (bash
, csh
i inne)
$ python3 nazwa.py
przy założeniu, że python3
jest nazwą programu uruchamiającego interpreter Pythona.
Interpretery poleceń w systemach uniksowych pozwalają uprościć uruchamianie skryptów za pomocą techniki zwanej shebang: jeżeli plikowi źródłowemu nadamy atrybut wykonywalności, i w jego pierwszym wierszu umieścimy wpis
#!/usr/bin/python3
o ile jesteśmy pewni ścieżki do interpretera, lub
#!/usr/bin/env python3
o ile wolimy pozostawić systemowi odnalezienie pliku interpretera, to plik ten będzie się dało uruchamiać poleceniem
$ ./nazwa.py
z poziomu powłoki systemowej (np. bash
).
Trick ten dotyczy wielu języków interpretowanych, nie tylko Pythona.
Dla interpretera Pythona wpis ten jest zwykłym komentarzem.
W tej metodzie polecenie postaci python plik.py
jest wywoływane w reakcji na manipulacje obiektami środowiska użytkowego.
Funkcja Otwórz
(ew. Uruchom
)
wywołana na ikonie pliku źródłowego nazwa.py
np. przez podwójne kliknięcie, <Enter> lub przez menu kontekstowe.
Jeżeli uruchamiany kod jest programem terminalowym, to przydzielone
mu w środowisku graficznym okno zostanie zamknięte natychmiast po
wykonaniu ostatniej instrukcji. Dlatego programy tego typu lepiej uruchamiać
z poziomu terminala znakowego. Można też tak zaprojektować program,
żeby po wydrukowaniu wyników zaczekał z zakończeniem pracy na reakcję użytkownika
(np. wykonując instrukcję input()
).
Niektóre zaawansowane edytory dają możliwość uruchamiania tworzonych w ich sesji programów.
SciTE obsługuje podświetlanie i zwijanie elementów składni Pythona. Po dostarczeniu odpowiedniego pliku konfiguracyjnego może także wyświetlać podpowiedzi dotyczące poleceń.
Ponadto SciTE pozwala uruchamiać programy bezpośrednio z poziomu edytora za pomocą funkcji menu:
Widok/[x]Pole wyników Narzędzia/Uruchom (F5)
lub jej odpowiednika w aktualnym języku interfejsu użytkowego.
To dobrodziejstwo wymaga, by ścieżka dostępu do interpretera Pythona
była wpisana do ścieżek systemowych (PATH
;
patrz podrozdział 5.1. poświęcony instalacji).
W systemach uniksowych SciTE nie obsługuje
wprowadzania danych wejściowych do programu przez okno Pole Wyników
.
Można tylko odczytywać z niego wyniki.
Możliwości Notepad++ są zbliżone do możliwości SciTE; oba edytory korzystają z tej samej biblioteki kodu źródłowego, udostępniającej komponent edycyjny o nazwie Scintilla. Notepad++ wymaga skonfigurowania, jeżeli chodzi o opcję uruchamiania programu. Robi się to wypełniając formularz dialogowy wywoływany z menu programu:
Run/Run python $(FULL_CURRENT_PATH) Save Name: Python Ctrl [x] + Shift [x] + [Klawisz] Alt [x]
(W przypadku, kiedy ścieżka do interpretera Pythona nie jest opisana w konfiguracji systemu,
w powyższym wpisie nazwę polecenia python
trzeba zastąpić pełną ścieżką,
np. c:\python27\python.exe
).
Uruchomienie bieżącego programu Pythona w terminalu tekstowym będzie wtedy możliwe przez opcję menu
Run/Python
lub przez zadeklarowany skrót klawiszowy.
Inną sensowną możliwością jest użycie dodatku przygotowanego dla programu Notepad++, który umożliwia uruchamianie skryptów napisanych w Pythonie.
Także ten edytor jest dość wygodny przy pisaniu prostych programów w Pythonie. Opcję uruchamiania kodu źródłowego trzeba samemu skonfigurować:
Edycja/Ustawienia/Programy zewnętrzne/Programy użytkowe i filtry/ Etykieta: Python Polecenie: xterm -e "python '%s'; read 'naciśnij Enter...'"
Uruchomienie kodu w zewnętrznym terminalu będzie wtedy wymagać użycia opcji
Zewnętrzne/Polecenia/Python
której warto przypisać skrót klawiszowy (np. <F5>).
Podobnym sposobem da się zaprogramować uruchamianie zewnętrznego debuggera (np. WinPDb) z poziomu menu Bluefish.
Edytor Emacs wyposażony jest we wszelkie udogodnienia służące tworzeniu i uruchamianiu kodu komputerowego napisanego w praktycznie dowolnym języku — w tym także w Pythonie.
Uruchomienie programu z poziomu Emacsa
przebiega następująco: po załadowaniu pliku źródłowego z rozszerzeniem
.py
opcje menu
Python/Start Interpreter Python/Eval buffer
odpowiednio: inicjują okno Emacsa z konsolą interpretera i uruchamiają program z załadowanego pliku. Wejście i wyjście tekstowe odbywa się przez konsolę w oknie.
Środowisko programistyczne różni się od edytora programisty przede wszystkim tym, że pozwala uruchamiać kod źródłowy w trybie diagnostycznym i w znacznym stopniu na bieżąco kontrolować jego wykonywanie.
IDLE jest graficznym środowiskiem do edycji i uruchamiania kodu źródłowego, dołączanym do każdej dystrybucji Pythona. Dlatego warto je znać, choć pod względem prostoty użytkowania przegrywa z innymi podobnymi narzędziami.
Plik źródłowy wczytany do edytora uruchomimy za pośrednictwem opcji
Run/Run module (F5)
PythonWin jest pełnym środowiskiem uruchomieniowym, wyposażonym w niezły edytor (korzystający, podobnie jak SciTE i Notepad++, z projektu Scintilla), zintegrowaną konsolę Pythona i debugger. Działa w systemach operacyjnych Windows.
Program w aktywnym oknie edycyjnym uruchamiamy za pomocą opcji menu
File/Go (F5)
lub ikonki „z biegnącym ludzikiem” na listwie narzędzi.
Pewną osobliwością PythonWin jest uruchamianie kolejnych programów w ramach jednej sesji interpretera. Powoduje to, że skutki działania programu w pamięci pozostają widoczne dla programów uruchamianych w następnej kolejności. Fakt ten może utrudniać znalezienie przyczyn błędów w testowanych za pomocą PythonWin programach.
Inne środowiska, jak WingIDE, Komodo, WinPDb mają swoje, nieco odmienne, lecz analogiczne sposoby uruchamiania wczytanego programu.
W niektórych środowiskach użytkowych język Python pełni rolę języka makropoleceń. Oznacza to, że istnieje możliwość uruchomienia takiego programu bez opuszczania środowiska, i że działanie takiego programu rozszerza możliwości środowiska o nową funkcjonalność.
Odsyłacze w przyszłość: OpenOffice — podrozdział 11.4.4., Gnumeric — podrozdział 11.4.6., inne.