Python ve své standardní knihovně obsahuje funkce i metody.
Funkce přijímá jeden nebo více argumentů a případně vrací hodnotu. Mezi vestavěné funkce Pythonu, které jsme už v tomto kurzu viděli, patří len(), chr(), ord(), input() a print(). Funkci zavoláme tak, že napíšeme její název následovaný argumenty:
name = input('Enter your name: ')
Metoda se podobá funkci, ale volá se nad konkrétním objektem. Například:
s = 'yoyo'
b = s.startswith('yo') # method call
Ve druhém řádku voláme metodu startswith() nad řetězcem s. Metodě předáváme řetězec 'yo'. Metoda vrátí hodnotu True, protože řetězec 'yoyo' skutečně začíná na 'yo'.
Výše jsme uvedli, že metoda se volá nad objektem. V Pythonu je každá hodnota objektem, takže objekty jsou například 3, False i 'yoyo'. (V některých jiných jazycích se technicky rozlišují objekty a jiné druhy hodnot.) Metody a související vlastnost zvaná třídy, o které budeme mluvit později, jsou základními stavebními prvky objektově orientovaného programování. Jazyk, který má metody a třídy, například Python, C++, Java nebo C#, se nazývá objektově orientovaný.
Ne všechny programovací jazyky mají funkce i metody. Například C má pouze funkce a klasická Java pouze metody. Python je v tomto ohledu kombinací obou přístupů. Díky tomu je jazyk pravděpodobně flexibilnější a pohodlnější, za cenu určité složitosti.
V tomto kurzu se brzy naučíme psát vlastní funkce a zanedlouho také vlastní metody a třídy.
Knihovna Pythonu obsahuje mnoho dalších užitečných metod pro řetězce. Například .lower() převede všechny znaky řetězce na malá písmena:
>>> s = 'YUMMY PIE'
>>> s.lower()
'yummy pie'
>>> s
'YUMMY PIE'
Všimněte si, že volání lower() vrátilo nový řetězec podobný s, ale se všemi znaky převedenými na malá písmena. Původní řetězec s nezměnilo; stále obsahuje velká písmena. Ve skutečnosti jej změnit ani nemohlo, protože řetězce v Pythonu jsou neměnné. Mnoho metod řetězců funguje podobně: vrací nový řetězec odvozený úpravou původního.
Další metody a operátory pro řetězce najdete v rychlé referenční příručce. Řetězce jsou iterovatelné, protože je lze procházet cyklem for. Jsou také sekvence, protože k jejich prvkům lze přistupovat zápisem s[i]. Později se seznámíme s dalšími iterovatelnými objekty a sekvencemi. V Pythonu je každá sekvence iterovatelná, ale některé iterovatelné objekty, například sys.stdin, nejsou sekvence.
Operace použitelné pro řetězce proto najdete ve třech částech referenční příručky: v oddílech o iterovatelných objektech, sekvencích a přímo o řetězcích.
Python obsahuje f-řetězce (f-strings), tedy formátované řetězce, do nichž lze vkládat hodnoty. Například:
>>> color1 = 'blue'
>>> color2 = 'green'
>>> f'The sky is {color1} and the field is {color2}'
'The sky is blue and the field is green'
Aby Python rozpoznal f-řetězec, napište bezprostředně před řetězec znak f. Vkládané hodnoty mohou být libovolné výrazy. Uvažujme například program, který načte dvě hodnoty a vypíše jejich součet. Bez f-řetězce bychom mohli napsat:
x = int(input('Enter x: '))
y = int(input('Enter y: '))
print('The sum of', x, 'and', y, 'is', x + y)
Pomocí f-řetězce můžeme poslední řádek napsat takto:
print(f'The sum of {x} and {y} is {x + y}')
Podle mého názoru se takový zápis snáze čte i píše.
Za každou vkládanou hodnotu lze volitelně přidat formátovací kód, který určuje, jak bude hodnota převedena na řetězec. Mezi běžné kódy patří:
Například:
>>> import math
>>> m = 127
>>> f'hex value is {m:x}'
'hex value is 7f'
>>> import math
>>> math.pi
3.141592653589793
>>> f'pi is {math.pi:.3f}'
'pi is 3.142'
Všimněte si, že Python číslo zaokrouhluje, nikoli pouze ořezává, na požadovaný počet číslic.
Před formátovací kód d nebo x lze vložit čárku (,), která způsobí seskupení číslic po třech a jejich oddělení čárkami:
>>> x = 2 ** 100
>>> f'{x:,d}'
'1,267,650,600,228,229,401,496,703,205,376'
Číslo před formátovacím kódem určuje šířku pole. Pokud je hodnota kratší, než je zadaná šířka, doplní se zleva mezerami:
>>> f'{23:9d}'
' 23'
>>> f'{723:9d}'
' 723'
>>> f'{72377645:9d}'
' 72377645'
Pokud šířce pole předchází 0, výstup se místo mezer doplní nulami:
>>> f'{23:09d}'
'000000023'
>>> f'{723:09d}'
'000000723'
>>> f'{72377645:09d}'
'072377645'
Existuje mnoho dalších formátovacích kódů pro podrobnější řízení výstupu. Úplný popis najdete v dokumentaci knihovny Pythonu.
Funkce input() a print() už známe. input() čte řádek ze standardního vstupu. print() vypisuje na standardní výstup. Ve výchozím nastavení jsou standardním vstupem a výstupem terminál; později si ukážeme, jak je přesměrovat do souboru nebo z něj.
V určitém okamžiku může vstup skončit. Pokud se čte z terminálu, konec vstupu lze označit stisknutím Ctrl+D (Linux nebo macOS) nebo Ctrl+Z a Enter (Windows).
Napišme program, který čte ze standardního vstupu čísla, každé na samostatném řádku, dokud vstup neskončí. Program vypíše jejich součet. Pomocí input() by při dosažení konce vstupu vznikla chyba. Místo toho můžeme použít objekt sys.stdin, který představuje standardní vstup programu. Lze jej procházet cyklem for; při každé iteraci získáme další vstupní řádek jako řetězec:
import sys
sum = 0
for line in sys.stdin: # for each line of standard input
n = int(line) # convert string to integer
sum += n
print('The sum is', sum)
Spusťme program a zadejme mu několik čísel:
$ python sum.py
3
4
5
^D
Na konci jsme zadali ^D (Ctrl+D), čímž jsme označili konec vstupu. Program nyní vypíše:
The sum is 12
Při spuštění programu lze přesměrovat standardní vstup tak, aby se četl ze souboru, a standardní výstup tak, aby se zapisoval do souboru.
Pro přesměrování vstupu použijte znak <. V textovém editoru vytvořme soubor test.in s tímto obsahem:
4
5
6
Nyní spusťme předchozí program a přesměrujme jeho vstup ze souboru test.in:
$ python sum.py < test.in
15
Znak > obdobně přesměruje výstup programu. Přesměrujme současně vstup i výstup:
$ python sum.py < test.in > test.out
$
Program se spustil, ale na terminálu nic nevypsal, protože jeho výstup byl přesměrován. Výsledek můžeme zobrazit v editoru, případně příkazem cat, který v Linuxu a macOS vypíše obsah souboru:
$ cat test.out
15
$
Mnoho domácích úloh v systému ReCodEx obsahuje ukázkový vstup a výstup. Každý ukázkový vstup si můžete uložit do souboru a program pak spouštět s přesměrováním vstupu z jednotlivých souborů. Je to pohodlnější než zadávat vstup pokaždé ručně.
Už jsme viděli, že cyklem for lze číst řádky ze sys.stdin. Každý získaný řetězec končí znakem nového řádku. Uvažujme program print.py, který čte všechny řádky ze standardního vstupu a kopíruje je na standardní výstup:
import sys
for line in sys.stdin:
print(line)
Předpokládejme, že textový soubor story.txt obsahuje tři řádky:
the beginning
the middle
the end
Spusťme program s přesměrovaným vstupem z tohoto souboru:
$ python print.py < story.txt
the beginning
the middle
the end
$
Všimněte si prázdných řádků navíc po každém vypsaném řádku. Každý řetězec získaný cyklem for totiž už obsahuje znak nového řádku. Například první řádek načtený ze souboru bude 'the beginning\n'. Když na tento řetězec zavoláme print(), vypíše se jeho vlastní nový řádek a potom ještě další nový řádek, který print() standardně přidává.
Pokud nechceme prázdné řádky navíc, můžeme použít metodu strip(), která odstraní bílé znaky ze začátku a konce řetězce. Mezi bílé znaky patří mezery i znaky nového řádku:
>>> ' one two three '.strip()
'one two three'
>>> 'down the street\n'.strip()
'down the street'
Upravme program print.py tak, aby každý řádek načtený ze standardního vstupu nejprve očistil metodou strip():
import sys
for line in sys.stdin:
line = line.strip()
print(line)
Nyní už program nebude vypisovat prázdné řádky navíc. Pokud chceme odstranit pouze koncový znak nového řádku a zachovat ostatní bílé znaky, můžeme místo toho použít:
line = line[:-1]
Funkce open() otevře soubor. Přijímá dva parametry: název souboru a volitelný řetězec režimu, který může obsahovat jeden nebo více těchto znaků:
Pokud režim neuvedete, soubor se otevře pro čtení v textovém režimu. V textovém režimu Python sjednocuje zápisy konce řádku a převádí je na '\n'. V tomto kurzu budeme používat pouze textový režim.
Funkce open() vrací objekt souboru. Při čtení je tento objekt iterovatelný, takže jej lze procházet cyklem for a postupně získávat řádky, podobně jako u sys.stdin. Pokud je soubor otevřen pro zápis, můžeme na něj zapisovat voláním metody write() pro každý řádek.
Po dokončení čtení nebo zápisu bychom měli zavolat close() a soubor zavřít. Následující program otevře soubory input.txt a output.txt, čte řádky ze vstupního souboru a každý řádek zapíše do výstupního souboru dvakrát:
input = open('input.txt', 'r') # open for reading ('r' is default mode)
output = open('output.txt', 'w') # open for writing
for line in input:
output.write(line) # write line to output
output.write(line) # write it again
input.close()
output.close()
Další metody pro vstup a výstup jsou uvedeny v rychlé referenční příručce Pythonu.
Když otevřete soubor, měli byste jej zavřít, i když program neočekávaně skončí chybou. Python nabízí speciální příkaz with, který to usnadňuje. Přiřadí objekt souboru (nebo jiný prostředek) proměnné a poté provede blok kódu. Jakmile blok z jakéhokoli důvodu skončí, objekt se automaticky uzavře, jako kdybychom zavolali jeho metodu close().
Přepišme předchozí program s použitím with:
with open('input.txt', 'r') as input: # open for reading ('r' is default mode)
with open('output.txt', 'w') as output: # open for writing
for line in input:
output.write(line) # write line to output
output.write(line) # write it again
Používat with při otevírání souborů je dobrým zvykem. Zajistí uzavření souboru i v případě, že program skončí chybou. Příkaz with funguje také s dalšími typy objektů, které je třeba uzavřít, například se síťovými sokety.
Seznamy jsou základním datovým typem Pythonu. Seznam vytvoříme tak, že do hranatých závorek vložíme řadu hodnot:
l = [3, 5, 9, 11, 15]
Seznam může obsahovat hodnoty různých typů:
l = ['horse', 789, False, -22.3]
Může obsahovat libovolný počet hodnot, případně být prázdný:
l = []
Funkce len vrací počet prvků seznamu:
len(['potato', 'tomato', 'tornado']) # returns 3
K prvkům seznamu přistupujeme pomocí indexů. První prvek má index 0 a poslední index len(l) – 1:
>>> l = [3, 5, 9, 11, 15]
>>> l[0]
3
>>> l[4]
15
Stejně jako u řetězců můžeme použít záporné indexy, které počítají od konce seznamu:
>>> l = [3, 5, 9, 11, 15]
>>> l[-1]
15
>>> l[-2]
11
Zápis výřezu funguje u seznamů stejně jako u řetězců:
>>> l = [3, 5, 9, 11, 15]
>>> l[1:3]
[5, 9]
>>> l[3:]
[11, 15]
Operátor in ověřuje, zda seznam obsahuje danou hodnotu:
>>> 77 in [2, 8, 77, 3, 1]
True
U řetězců se operátor in chová trochu jinak. U seznamů neověřuje, zda se v seznamu nachází podseznam:
>>> [8, 77] in [2, 8, 77, 3, 1]
False
Na rozdíl od řetězců jsou seznamy v Pythonu měnitelné. Hodnoty lze měnit podle indexu:
>>> l = [3, 5, 9, 11, 15]
>>> l[0] = 77
>>> l[3] = 99
>>> l
[77, 5, 9, 99, 15]
Délka seznamu se může v průběhu programu měnit. Metoda append() přidá do seznamu jeden prvek:
>>> l = [3, 5, 9, 11, 15]
>>> l.append(20)
>>> l.append(30)
>>> l
[3, 5, 9, 11, 15, 20, 30]
Metodu append() často používáme k postupnému sestavování seznamu v cyklu. Například můžeme vytvořit seznam druhých mocnin čísel od 1 do 10:
l = []
for i in range(1, 11): # 1 .. 10
l.append(i * i)
Metoda extend() přidá do seznamu řadu prvků. Operátor += je jejím ekvivalentem:
>>> l = [2, 4, 6]
>>> l.extend([8, 10])
>>> l
[2, 4, 6, 8, 10]
>>> l += [12, 14]
>>> l
[2, 4, 6, 8, 10, 12, 14]
Metoda insert() vloží prvek do seznamu na určenou pozici:
>>> l = [3, 5, 9, 11, 15]
>>> l.insert(2, 88)
>>> l
[3, 5, 88, 9, 11, 15]
Operátor del může podle indexu odstranit jeden nebo více prvků seznamu:
>>> l = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'grape']
>>> del l[1]
>>> l
['orange', 'pear', 'banana', 'kiwi', 'grape']
>>> del l[2:4]
>>> l
['orange', 'pear', 'grape']
Můžeme také přiřadit hodnoty do výřezu seznamu a nahradit jej libovolnou posloupností hodnot:
>>> l = [2, 4, 6, 8, 10]
>>> l[1:3]
[4, 6]
>>> l[1:3] = [100, 200, 300]
>>> l
[2, 100, 200, 300, 8, 10]
Funkce list() převede libovolnou sekvenci na seznam:
>>> list('watermelon')
['w', 'a', 't', 'e', 'r', 'm', 'e', 'l', 'o', 'n']
>>> list(range(120, 130))
[120, 121, 122, 123, 124, 125, 126, 127, 128, 129]
Stejně jako řetězce jsou seznamy iterovatelné, takže je lze procházet cyklem for. Jsou také sekvence, protože k jejich prvkům lze přistupovat pomocí l[i]. Operace se seznamy proto najdete ve třech oddílech referenční příručky: iterovatelné objekty, sekvence a seznamy.