prev up next title end end

2. Hodnoty, výrazy a příkazy

  1. Hodnoty a typy objektů
  2. Typy datových objektů
  3. Booleovské hodnoty a výrazy
  4. Konverze typu
  5. Jména a klíčová slova
  6. Operátory a operandy
    1. Aritmetické operátory
    2. Operátory rozšířeného přiřazení
    3. Bitwise operátory
    4. Relační operátory
    5. Logické operátory
    6. Speciální operátory
    7. Hvězdičkové operátory
    8. Pořadí operací
    9. Podtržítka
  7. Proměnné
    1. Změna přiřazení
    2. Aktualizace proměnné
    3. Anotace proměnných
  8. Glosář
  9. Cvičení

2.1 Hodnoty a typy objektů

Ústředním pojmem objektově orientovaného (viz Kap. 10.1) programovacího jazyka Python je objekt - coby instance programové struktury, zvané třída.

Celou plejádu možných objektů lze zhruba rozdělit do dvou skupin:

  1. Na datové objekty, obsahující údaje (data), s nimiž lze pomocí jiných objektů pracovat - tyto objekty jsou blíže popsány v odstavci 2.2.
  2. Na provozní objety, schopné s uvedenými datovými objekty manipulovat - příkladem těchto objektů budiž funkce, metody a třídy (viz).

Každý objekt má jedinečnou hodnotu (value), typ (type) a identitu (ID).

Hodnota je inherentní význam datového objektu, vyjadřující množství (např. číslo), vlastnost (např. barvu) či jedinečnost (např. textový řetězec), s nímž může být v rámci výpočtu manipulováno. Každá hodnota je nositelem nějakého typu.

Typ je název třídy, z níž byl objekt odvozen. Typ objektu vymezuje množinu podporovaných operací a rovněž definuje možné hodnoty objektu. Pokud si nejsme jisti, k jakému typu neboli třídě objekt patří, zjistíme to vestavěnou funkcí type(), jenž je součástí Pythonu:

>>> type("Hello, World!")    # Text v uvozovkách je objekt
<class 'str'>                  typu 'string' neboli řetězec
>>> type(17)                 # Celé číslo je objekt typu    
<class 'int'>                               'integer'
>>> type(3.2)                # Desetinné číslo je objekt
<class 'float'>                             typu 'float'

Vězme tedy, že řetězce (strings) patří k typu str a celá čísla (integers) k typu int. Čísla s desetinnou čárkou (v Pythonu tečkou) patří k typu float. Přehled typů je uveden v následující části 2.2.

A což objekty jako "17" a "2.3"? Vypadají jako čísla, ale jsou v uvozovkách.

>>> type("17")
<class 'str'>
>>> type("2.3")
<class 'str'>

Jsou to řetězce. Řetězce mohou být v Pythonu uzavřeny v jednoduchých ('), dvojitých (") nebo i trojitých (''') uvozovkách. Uvnitř dvojitých uvozovek mohou být uvozovky jednoduché a obráceně: 'Pravil "Ne!" '.

Identita objektu je vyjádřena jeho identifikačním číslem (ID), které je adresou paměťového místa, ve kterém je aktuálně hodnota (v binární formě) uložena.
Některé objekty mohou mít explicitně přiřazené jméno, obecně označované jako proměnná. Typ proměnné je dán typem jí přiřazené hodnoty:

>>> num = 17; type(num), type(17)   # num je jméno proměnné           
(<class 'int'>, <class 'int'>)      # type(num) = type(17)   
>>> id(num), id(17)        
(1835649200, 1835649200)            # zde id(num) == id(17)

Komentář na posledním řádku nutno brát s jistou rezervou, neboť ne vždy id(name) == id(value). Vždy však platí, že identita existujícího objektu je v rámci jedné seance neměnná.

Vznik objektu

Pro zvídavé

Není na škodu si uvědomit, že objekt (základní entita Pythonu) má tři stadia existence:

  1. jako použitelná možnost, daná pravidly jazyka Python
  2. použitá možnost, daná deklarací objektu ve zdrojovém kódu (skriptu); toto stadium má dvě variety - objekty předdefinované (built-in), které jsou součástí programového vybavení Pythonu a objekty deklarované uživatelem ve skriptu
  3. realizovaná možnost, daná provedením zdrojového kódu interpretem

Nový objekt vzniká zpracováním programového textu interpretem Pythonu, přičemž je ověřováno, zda takový objekt již je či není v paměti počítače uložen.
Přiřazování identifikačních čísel k objektům je ve výlučné kompetenci Interpreta a do jisté míry se řídí řadou známých pravidel.

Opuštěná hodnota zůstává v paměti i po změně přiřazení. Z paměti zmizí až po ukončení aktuální seance Pythonu působením procedury garbage collection.


2.2 Typy datových objektů

Všechny vestavěné typy Pythonu jsou typy datové, s výjimkou typu elipsis, jehož jediným literálem jsou tři tečky.
Nutno také uvést, že některé typy objektů (- singletony) obsahují pouze jedinou hodnotu , jiné (- složené datové typy) obsahují více hodnot .

Následující stručný přehled datových typů jazyka Python je zároveň přehledem jejich možných literálů (přímých zápisů jejich hodnoty). V přehledu jsou nejprve uváděny názvy typů, posléze jejich literály.


  • Speciální typy

  • Numerické typy (numbers)

  • Sekvence
  • Sekvence je uspořádaná a indexovatelná (subscriptable) množina hodnot, které nemění své pořadí:

    Následující sekvenční typy pracují se sekvencemi bitů (viz 7.2):

    Prvky všech sekvenčních typů jsou interně indexovány pořadovým číslem (indexem), počínajícím nulou (viz 3.1). To umožňuje přímý přístup k elementu sekvence.

    U všech výše uvedených sekvenčních typů lze uplatnit tyto operace:
    len(sekv), elem in sekv, úsek: seq[i:j], min(sekv), max(sekv), s1+s2, sekv*number.

  • Kolekce
  • Částečně uspořádaná množina hodnot, která nepodporuje indexování - s výjimkou slovníku, který při výběru páru používá místo číselného indexu hodnotu jeho klíče (jímž může být i číslo).

    Sekvence a kolekce jsou složené datové typy, sumárně označované jako kontejnery.

    Hodnoty specielních a numerických typů, jakož i typů tuple, range, string, bytes, frozenset, memoryview nelze dodatečně změnit; říkáme, že jsou neměnitelné (immutable).

    Hodnoty typů list, set, dict, bytearray lze po jejich vytvoření dodatečně změnit; říkáme, že jsou měnitelné (mutable) - změna hodnoty nevyvolá změnu ID.

    Pro zvídavé:

    Specielním představitelem kontejneru je útvar, zvaný array, jenž je obdobou typu list, obsahující řadu hodnot stejného typu - viz Kap. 7.7.2.

    Poznámka 1:

    Python nemá datový typ pro jeden znak, v jiných jazycích označovaný termínem char . Nahrazuje jej řetězcem s jedním prvkem - např   "a".

    Kromě uvedeného výčtu datových typů disponuje Python řadou dalších typů jako module, function, method, class, ... atd. Vlastně lze říci, že 'všechno v Pythonu je objekt' a 'každý objekt je nějakého typu'.

    Poznámka 2:
    Počítání s desetinnými čísly typu float není úplně přesné:

    >>> f = 0.1 + 0.1 + 0.1 ; f             # viz Poznámka 3
    0.30000000000000004
    

    Existuje modul decimal, který (kromě jiného) ošetřuje výpočty s desetinnými čísly tak, že jsou rychlejší a přesnější.

    >>> from decimal import Decimal
    
    >>> x = Decimal('0.1')
    >>> y = Decimal('0.1')
    >>> z = Decimal('0.1')
    
    >>> s = x + y + z; s; print(s)         # viz Poznámka 3
    Decimal('0.3')
    0.3
    

    Poznámka 3:
    Invokace výrazu za středníkem ; chodí pouze v interaktivním režimu konzoly. Nechodí při spuštění skriptu ze souboru ~.py.


    2.3   Booleovské hodnoty a výrazy

    Pythonovský typ pro uložení hodnoty True nebo False zvaný bool je pojmenován po britském matematikovi George Booleovi, jenž vytvořil tak zvanou booleovu algebru, která je základem moderní počítačové aritmetiky.

    Jsou pouze dvě booleovské hodnoty: True a False. Velká počáteční písmena jsou důležitá, neboť true a false booleovskými hodnotami nejsou.

    >>>type(True) 
    <class 'bool'>
    >>>type(true)
    Traceback (most recent call last):
    >>File "<stdin>", line 1, in <module>
    NameError: name 'true' is not defined
    

    Booleovský výraz (prostěji podmínka) je výraz, který vede k boooleovské hodnotě. Tento výraz má tuto zavedenou skladbu:

    <levý operand> relační či specielní operátor <pravý operand>
    
    >>> 5 == 5
    True
    >>> 5 is not 5
    False
    

    Vestavěná funkce bool() vrací booleovskou hodnotu čísel a řetězců. U číselných typů generují nulové hodnoty výstup False, nenulové hodnoty výstup True. Prázdné řetězce dávají False, neprázdné řetězce dávají True:

    >>> bool(1)
    True
    >>> bool(0)
    False
    >>> bool("No !")           # neprázdný řetězec
    True
    >>> bool("")               # prázdný řetězec
    False
    >>> bool(3.14159)          # nenulová hodnota
    True
    >>> bool(0.0)              # nulová hodnota
    False
    

    2.4 Konverze typu

    Změna typu neboli konverze typu se provádí pomocí řady vestavěných funkcí.

    Funkce str(value, base) přijímá objekty uvedených základních typů a přemění jej na objekt typu string.

    >>> str(32), str(32.12), str(3+2j)      # deklarace entice
    ('32', '32.12', '3+2j')                 # entice (tuple) stringů
    
    >>> str({3.6, "cat", True})             # konverze setu
    "{True, 3.6, 'cat'}"
    

    Funkce float() přijímá literály numerického typu int a přemění jej na typ float, například:

    >>> float(12), float(0b10001), float(False)
    (12.0, 17.0, 0.0)
    

    Funkce int(value, base) přijímá literály a proměnné typu number (mimo 'complex'), bytes a str a přemění jej na typ integer, například:

    >>> int(32.12), int(0b100000), int(True)
    (32, 17, 1)
    

    Pro převod celého čísla do jiného číselného formátu slouží funkce:

    Funkce hex(integer) přijímá celé číslo a přemění jej na číslo se základem 16.

    Funkce oct(integer) přijímá celé číslo a přemění jej na číslo se základem 8.

    Funkce bin(integer) přijímá celé číslo a přemění jej na číslo se základem 2.

    Všechny formáty celého čísla, vytvořené funkcemi hex(), oct(), bin(),   jsou typu integer:

    >>> hex(32), oct(32), bin(32)
    ('0x20', '0o40', '0b100000')    # zobrazení jako string, ale:
    type(0x20), type(0o40), type(0b100000)
    (<class 'int'>, <class 'int'>, <class 'int'>)
    

    Převod znaku na pořadové číslo systému Unicode provádí funkce ord('znak')

    >>> ord(" "), ord("m"), ord("&")       # mezera je také znak
    (32, 109, 38)
    

    Převod přadového čísla systému Unicode na příslušný znak provádí funkce chr('unicode')

    >>> chr(32), chr(109), chr(38)   
    (' ', 'm', '&')
    

    Pro převod sekvence (list, range, tuple, set, string, bytes) na sekvenci jiného typu slouží funkce list(), tuple(), set(), například:

    >>> list("a5 True")                  # list z řetězce   
    ['a', '5', ' ', 'T', 'r', 'u', 'e']
    >>> tuple("a5 True")                 # tuple z řetězce                     
    ('a', '5', '', 'T', 'r', 'u', 'e')
    >>> set("a5 True")                   # set z řetězce
    {'u', 'r', '', 'T', 'e', '5', 'a'}
    

    Pro převod entice, slovníku či setu na slovník slouží funkce dict() - viz kap. 11.1, třetí ukázka.

    >>> tup = (("a", 5), ("b", True))      # entice entic
    >>> dit = dict(tup); dit               # dict from tuple
    {'a': 5, 'b': True}
    
    >>> lup = [("a", 5), ("b", True)]      # seznam entic
    >>> lip = dict(lup); lip               # dict from list
    {'a': 5, 'b': True}
    
    >>> sup = {("a", 5), ("b", True)}      # set entic
    >>> sip = dict(sup); sip               # dict from set
    {'a': 5, 'b': True}
    

    Pro převod reálných čísel na číslo komplexní slouží funkce complex(real, imag).

    >>> complex(3.2, 12)
    (3.2+12j)
    

    Funkce ascii(string) přijímá řetězec a vrací jej doplněný zpětnými lomítky u znaků, které nejsou obsaženy v kódování ASCii.

    >>> ascii("žížala"), ascii("oves")
    ("'\\u017e\\xed\\u017eala'", "'oves'")
    

    2.5 Jména a klíčová slova

    Jména proměnných, jakož i funkcí a tříd, mohou být libovolně dlouhá. Mohou obsahovat jak písmena tak číslice, ale musejí začínat písmenem a nesmějí obsahovat mezeru. I když je přípustné použít velká písmena, z konvenčních důvodů to neděláme. Pokud tak učiníme, musíme si uvědomit, že velikost písmena hraje roli. Bruce a bruce jsou různá jména.

    Podtržítko '_' se ve jménu smí použít (naopak pomlčka '--' se používat nemá). Často se používá u jmen s více slovy, jako je moje_jmeno nebo price_of_tea_in_china. Podtržítko na počátku názvu mívá speciální význam, takže jej zatím raději takto nepoužívejte.

    Dáme-li proměnné nepřípustné jméno, obdržíme syntaktickou chybu:

    >>> 76trombones = "big parade"
    SyntaxError: invalid syntax
    >>> more$ = 1000000
    SyntaxError: invalid syntax
    >>> class = "Computer Science 101"
    SyntaxError: invalid syntax
    

    76trombones není legální, protože nezačíná písmenem, more$ není legální, protože obsahuje nedovolený znak, označení dolaru. Co je ale špatného na class ?

    Ukazuje se, že class je jedno z klíčových slov Pythonu. Klíčová slova jsou vyhrazená slova a nemohou být použita jako jména proměnných.

    Python má aktuálně třicet dva plus tři klíčová slova:

    and     as        assert  async    await     break    
    class   continue  def     del      elif      else     
    except  finally   for     from     global    if
    import  in        is      lambda   nonlocal  not
    or      pass      raise   return   try       while   
    with    yield     True    False    None
    

    Aktuálně platný seznam klíčových slov získáme zadáním příkazu:

    >>> help("keywords")
    

    2.6 Operátory a operandy

    Operátor je znak, zastupující funkci - prefixovou (stojící před operandem), infixovou (stojící mezi operandy) a postfixovou (stojící za operandem či funkcí - v Pythonu se nepoužívá).

    Z hlediska použitých operandů rozeznáváme

    2.6.1   Aritmetické operátory

    Aritmetickými operátory jsou znaky pro sčítání +, odčítání -, násobení *, umocňování **, dělení /, celočíselné dělení //, a operátor modulo % (dělení s celočíselným zbytkem).
    Pořadí důležitosti (precedence) je následující: Závorky | Umocňování a odmocňování | Násobení a dělení | Sčítání a odčítání.

    Operátor + lze kromě numerických hodnot použít také pro operandy typu str, list, tuple, bytes a bytearray, nikoliv však pro range, dict, set a frozenset:

    >>> "naše" + " prasátko"                      # string
    'naše prasátko'
    >>> ["naše"]+["prasátko"]   
    ['naše', 'prasátko']                          # list
    ("naše",)+("prasátko",)
    ('naše', 'prasátko')                          # tuple
    >>> b"our" + b" little pig"            
    b'our little pig'                             # bytes
    >>> bytearray(" naše", "utf-8") + bytearray(" prasátko", "utf-8")
    bytearray(b' na\xc5\xa1e pras\xc3\xa1tko')    # bytearray 
    

    Výše uvedené operandy lze rovněž násobit celým číslem. Objeví-li se na místě operandu proměnná, je kompilátorem zaměměna za svou hodnotu před tím, než se operace provede:

    >>> hele, mese = "hele", "mese "
    >>> (hele + mese)*3      # záporné číslo vrátí prázdný řetězec
    'helemese helemese helemese '
    

    Popsané součty operandů (kromě čísel) provádí Python při kompilaci v rámci zjednodušení (redukce) výrazů. U řetězců se tato procedura označuje jako zřetězení (concatenation).

    Operátor celočíselného dělení // (floor division) zaokrouhluje kladný podíl směrem dolů. Pracuje i s desetinnými čísly.

    >>> minute = 59 
    >>> minute // 60  
    0
    >>> -minute // -60.0
    0.0
    

    Záporný podíl je zaokrouhlován směrem k minus nekonečno.

    >>> -minute // 60.0  
    -1.0
    

    Operátor modulo pracuje s celými čísly (číselnými výrazy) a poskytuje zbytek při dělení prvního operandu druhým. V Pythonu jej označujeme znakem pro procento ' % '. V pořadí operací má stejnou preferenci jako násobení.

    >>> 7 % 3.0     
    1.0
    

    Ukazuje se, že modulo operátor je překvapivě užitečný. Na příklad, můžeme zjistit, zda jedno číslo je dělitelné druhým: je-li x % y == 0, pak x je dělitelné číslem y.

    Lze jím také oddělit krajní číslice zprava od zadaného čísla. Například, x % 10 vyčlení nejkrajnější číslici čísla x zprava (při základu 10). Podobně x % 100 vyčlení dvě poslední číslice.

    Použití operátoru modulo (%) si ukážeme na pěkném příkladu převodu vteřin na hodiny, minuty a zbývající vteřiny:

    secs_celk = int(input("Kolik vteřin celkem?"))
    hodiny = secs_celk // 3600
    secs_navic = secs_celk % 3600
    minuty = secs_navic // 60
    sekundy = secs_navic % 60
    
    print("Celkem vteřin: ", secs_celk)
    print("Hodin, minut, vteřin: ", hodiny, minuty, sekundy) 
    

    2.6.2   Operátory rozšířeného přiřazení

    Rozšířené (augmented) přiřazení je kombinace binární operace (+, -, *, /, %, **, //) a příkazu přiřazení (=) v jednom výraze. Toto přiřazení provede změnu hodnoty existující proměnné:

       Operátor    Příklad    Náhrada za
         =    x = 5     x = 5
         +=    x += 3     x = x + 3
         -=     x -= 3     x = x - 3
         *=     x *= 3      x = x * 3
         /=    x /= 3     x = x / 3
         %=    x %= 3     x = x % 3
         //=    x //= 3     x = x // 3
         **=    x **= 3     x = x ** 3
         &=     x &= 3     x = x & 3
         |=    x |= 3     x = x | 3
         ^=     x ^= 3      x = x ^ 3
         >>=    x >>= 3     x = x >> 3
         <<=    x <<= 3     x = x << 3

    Novějším (Python 3.8) způsobem přiřazení je přiřazení ve tvaru (var := val), označované jako přiřazení s výrazem. Pro zavedený operátor (:=) se ujalo označení mroží operátor.

    Prostý příkaz přiřazení (mrož = False) nevrací hodnotu:
    Přiřazení s výrazem vrací hodnotu: 
    >>> (mrož := False)                         
    False
    >>> (u := 5 + 3*2)                     
    11
    Mrožík má rád kulaté závorky, bez závorek produkuje Syntax 
    Error. S jinými než kulatými naloží takto:
    >>> {mrož := False}; [u := 5 + 3*2]
    {False}
    [11]
    

    2.6.3   Bitwise operátory

    Bitwise operátory provádějí logické operace AND, OR, NOT, operaci XOR, jakož i operace levého a pravého posunu na binárních řetězcích, což jsou sekvence nul a jedniček.

    Tyto operátory nejprve převedou celá čísla svých operandů do binárního formátu stejné délky, na tomto formátu provedou bit za bitem (bitwise) předepsanou operaci a výsledek posléze převedou zpět na celé číslo.
    Příklady v následující tabulce jsou vyčísleny pro x,y = 12, 5 (0b1100, 0b0101):

    Operátor Význam Příklad
       &    bitwise AND    1)     x & y     ->   4    (0b100)
       |   bitwise OR    2)     x | y      ->  13   (0b1101)
       ~   bitwise NOT    3)      ~x       -> -13  (-0b1101)
       ^   bitwise XOR    4)    x ^ y     ->   9   (0b1001)
       <<    bitwise left shift    5)   x << 2   ->  48  ('0b110000')
       >>   bitwise right shift    6)   x >> 2   ->   3   ('0b11')

    Poznámka:
    Operátor | se rovněž používá u množinové operace sjednocení (union).

    Popisy operací:

    1. Vrací 1, jsou-li oba odpovídající bity = 1, jinak vrací 0.
    2. Vrací 1, je-li alespoň jeden z odpovídajících bitů = 1, jinak vrací 0.
    3. Vrací doplněk (komplement) čísla x k číslu 1: ~x = -(x+1)
    4. Vrací 1, je-li jeden z bitů = 1 a druhý = 0; jinak vrací 0.
    5. K binárnímu tvaru levé hodnoty přidá zprava nuly v počtu pravého čísla.
    6. Od binárního tvaru levé hodnoty odebere zprava numera v počtu pravého čísla.

    Užitečné vztahy:

    bin(~12)        --> '-0b1101'   # ~12 = -(10+1) = -13
    bin(a^b)        --> ' 0b1001'
    int('110000',2) --> 48          # dclr-tto int('0b110000',2)
    

    Binární systém vyžaduje více paměťového prostoru než decimální systém ale je méně komplikovaný pro uplatnění v hardwaru počítače.

    2.6.4   Relační operátory

    Relační operátory vyjadřují tvrzení o kvantitativním vztahu mezi dvěma hodnotami. Jsou to tyto operátory:

        x == y                # x je rovno y
        x != y                # x není rovno y
        x >  y                # x je větší než y
        x <  y                # x je menší než y
        x >= y                # x je větší nebo rovno y
        x <= y                # x je menší nebo rovno y
    

    Jednotlivé tvrzení může být buď pravdivé nebo nepravdivé.

    >>> 5 < 3
    >>> False
    >>> 5/3 < 10
    >>> True
    

    Rovnítko (=) není operátorem, nýbrž znakem pro přiřazení hodnoty ke jménu. Tato veledůležitá vázací operace (binding) umožňuje pracovat s objekty prostřednictvím jejich jmen.

    Je nutné rozlišovat mezi pojmem rovnost (equality --> ==) a totožnost (identity --> is):

    >>> x, y = [1, 2, 3], [1, 2, 3]
    >>> x == y; x is y               --> True, False
    

    2.6.5   Logické operátory

    Logické (booleovské) operátory provádějí některé logické operace se zadanými operandy. Tyto operátory jsou tři: and , or a not. Jak vidíme, jsou to zároveň klíčová slova. Význam těchto operátorů je podobný jejich významu v češtině (a, nebo, ne).
    Například, výrazy x > 0 and x < 10 jsou pravdivé podle pravidel formální logiky pouze tehdy, jsou-li pravdivá obě tvrzení, to jest, je-li x větší než 0 a menší než 10.

    Tvrzení n%2 == 0 or n%3 == 0 je pravdivé, je-li alespoň jedna z podmínek pravdivá, to jest, je-li číslo dělitelné dvěma nebo třemi.

    Konečně, operátor not neguje následující booleovský výraz, takže not(x > y) je pravda, je-li x > y nepravda; to jest je-li x menší nebo rovno y.

    2.6.6   Speciální operátory

    Operátory totožnosti (identity) - is a is not ověřují, zda dva objekty mají stejné ID i stejnou hodnotu:

    >>> x1 = y1 = 5
    >>> x2 = y2 = "hej" 
    >>> x1 is not y1          # False  - operandy jsou identické
    >>> x2 is y2              # True   - id(x1) == id(y1)
    

    Operátory příslušnosti (membership) in a not in ověřují, zda je zkoumaná proměnná přítomna v zadané sekvenci (string, list, tuple, set a dictionary):

    >>> x = "Nazdárek!"               # string
    >>> y = {1:"a", 2:"b"}            # dictionary (slovník)
    
    >>> 'H' not in x                  # True
    >>> 1 in y                        # True
    

    2.6.7   Hvězdičkové operátory

    S hvězdičkami se nám v Pythonu roztrhl pytel. K původním aritmetickým operátorům pro násobení (*) a umocňování (**) máme aktuálně ještě:

    1. hvězdičky jako regulační znaky ve výčtu parametrů funkce; samotná hvězdička přikazuje aby všechny následující parametry přijímaly pouze párové argumenty funkce; doplňkem k hvězdičce ve výčtu parametrů je lomítko ve výčtu parametrů, které nařizuje aby všechny předcházející parametry přijímaly pouze poziční argumenty funkce -viz Kap. 4.2.2
    2. hvězdičky jako dekorátory variadických parametrů či argumentů *args pro sekvence a **kwargs pro slovníky - viz Kap.4.2.3 a 4.2.4

    2.6.8 Pořadí operací

    Objeví-li se ve výrazu více než jeden operátor, závisí pořadí výpočtu na pravidlech o pořadí operací. Python (až na výjimky) respektuje stejná pravidla, jaká se používají v matematice.

    Operátor Název, použití
      ()   závorky
      a**n,  a**(1/n)   umocnění, odmocnění
      +x, -x,   ~x     unární +, - ,   bitwise NOT
      *,  /,  //,  %    aritmetické operace
      +, -   aritmetický součin, podíl
      <<, >>   bitwise left shift, bitw. right shift
      &, ^, |   bitwise AND, XOR, OR - dle pořadí
      <, <=, >, >=;  ==, !=   relace;  rovná se, nerovná se
      (+ - * / ** // %) =   složené přiřazení (+=, *=, ...)
      not, and, or   logické operátory - dle pořadí
      is, is not   operátory identity
      in, not in   operátory příslušnosti
      :=   'mroží' operátor

    Téměř všechny operátory se stejnou prioritou jsou vyhodnocovány zleva doprava (jsou asociativní zleva).

    >>> 7 * 3 // 2          # (7 * 3) // 2
    10
    

    Opakované mocniny jsou vyhodnocovány zprava doleva (jsou asociativní zprava).

    2**3**2 # 2**(3**2) 512 >>> 7*8**(1/3) # 7 * 8**(1/3) 14.0

    Některé operátory nemají asociativitu a řídí se jinými pravidly, například:

    x < y < z     -->  x < y and y < z
    

    2.6.9 Podtržítka

    Podtržítka mají různý význam v různých situacích.

    1. Lze je použít jako oddělovač skupiny čísel:

      >>> mils = 1.2 * 1000**2
      >>> mils == 1_200_000
       True
      

      Obdobně lze oddělovat části binárního, oktálního a hexadecimálního čísla:  0b_100010o_21,   0x_11.

      Zajímavé na formátu nedekadických čísel je mimo jiné také to, že při invokaci se vracejí v dekadické formě:

      >>> bin, oct, hex = 0b_0010, 0o_64, 0x23ab (nerozděleno)
      >>> print(bin,",", oct,",", hex)
      2 , 52 , 9131                 # vrácen dekadický formát        
      
    2. V konzole interpreta představují poslední uloženou hodnotu výrazu:
      >>> 2 + 3
      5
      >>> _ * 3
      15
      
    3. Vyjadřují anonymní hodnotu:
      >>> for _ in range(6):
              print(_*_, end=" ")
      0 1 4 9 16 25
      
    4. Podtržítko místo jména proměnné způsobí nepoužití odpovídající pozice ve výčtu přiřazovaných hodnot:
      # Ignorována jedna hodnota:
      >>> a, _, b = (1, 2, 3)
      >>> print(a,",", b)                    # --> 1 , 3
      
      # Ignorováno více hodnot:
      >>> c, *_, d = 1, 2, 3, 4, 5
      >>> print(b,",", c)                    # --> 1 , 5
      
    5. Jednoduché podtržítko jako přípona slouží k rozlišení aktuálně deklarovaného jména od stejnojmenného klíčového slova:
      >>> def pattern(name, class):    # class je klíčové slovo
      SyntaxError: "invalid syntax"  
      
      >>> def pattern(name, class_):   # OK
              pass                              
      
    6. Jednoduché podtržítko jako předpona jména vyjadřuje pouze upozornění, že deklarovaná třída, metoda, funkce nebo modul je zamýšlen pro interní použití uvnitř aktuálního modulu, třídy nebo paketu. Externímu použití však bráněno není:
      class myClass:
          def __init__(self):
              self._bar = "Aleluja!"
      
      >>> myc = myClass(); myc._bar
      'Aleluja!'
      
    7. Dvojité podtržítko před jménem atributu třídy je signál pro kompilátor aby v interním seznamu __dir__ připojil název třídy k názvu atributu (viz dir(obj)), čímž zamlží jeho existenci. Popsaný proces se označuje jako komolení názvu (name mangling):
      class myClass:
         def __init__(self):
            self.__x = 20         # privátní název atributu
         def __myFunc(self):      # privátní název atributu
            print("Hello, World!")     
       
      obj=myClass()                     # instance třídy
      

      Názvy s předsazenými dvojitými podtržítky jsou externě nepřístupné:

      >>> obj.__x
      AttributeError: 'myClass' object has no attribute '__x'
      

      Zkomolené (mangled) názvy atributů __x, __myFunc() mají tvar :   _myClass__x, _myClass__myFunc(). Pouze v této formě jsou externě přístupné:

      >>> obj._myClass__x; obj._myClass__myFunc()
      20
      Hello, World!
      
    8. Dvojitá podtržítka před i za názvem (double underscores - dunders) metody označují speciální metodu třídy - viz kapitola 12.8.


    2.7 Proměnné

    Proměnná je uživatelské jméno, které odkazuje na přiřazený objekt, uložený pod identifikačním číslem (ID) v paměti počítače. Typ proměnné je dán typem přiřazeného objektu. Jméno bez přiřazeného objektu není akceptováno (ani mu není přiřazeno ID). Jména proměnných jsou case-sensitive, pomlčka uvnitř slova není povolena, jen podtržítko.

    # Příklady názvů proměnných:
    >>> a, a_a, A, aA,       
    

    Podle zavedené konvence jsou jména, počínající velkým písmenen, vyhražena pro názvy tříd. Není doporučován ani formát "aA".

    Objekt na pravé straně ke jménu na levé straně připojuje příkaz přiřazení, vyjádřený operátorem přiřazení (=). Vše, co umístíme na pravou stranu operátoru přiřazení, musí Python znát nebo umět vytvořit:

    >>> n = "hosana"           # OK, objekt typu string
    >>> pi = 3.14159           # OK, objekt typu float
    >>> x = ping      
    NameError: 'ping' is not defined
    >>> ping = 5; type(ping)
    <class ´int´>              # OK, objekt typu integer
    

    Před vlastním přiřazením se vyhodnotí případný výraz na pravé straně.

    >>> a = 5 + 3; a
    8
    

    Vazba jména na objekt se vyskytuje ve dvou místech:

    1. nejprve tam, kde je tato vazba deklarována, to jest v souboru (modulu) či v definici třídy nebo funkce
    2. poté je tato vazba zapsána do slovníku (jmenného registru) oblasti, příslušné místu deklarace

    2.7.1   Změna přiřazení

    Stejnému jménu lze postupně přiřazovat různé hodnoty (objekty):

    >>> bruce = 5
    >>> bruce
    5
    >>> bruce = 7; bruce
    7
    

    Nové přiřazení ruší přiřazení předchozí.

    2.7.2   Aktualizace proměnné

    Nejběžnější formou změny přiřazení je aktualizace, kdy nová hodnota proměnné závisí na její předchozí hodnotě, například:

    x = 6; id(x)                              # inicializace 
    2161740743056
    x = x + 1; x; id(x)                       # aktualizace
    7
    2161740743088
    

    Aktualizace proměnné přičtením hodnoty 1 se nazývá increment, aktualizace odečtením hodnoty 1 se nazývá decrement. Aktualizovaná proměnná musí mít předem přiřazenou počáteční hodnotu (viz inicializace).

    Aktualizaci proměnné lze s výhodou provádět i pomocí operátorů rozšířeného přiřazení  +=  -=  *=  /=  //=  %=   (viz 2.6.2).

    >>> y = 6
    >>> y += 1; y    
    7
    

    2.7.3   Anotace proměnných

    Anotace proměnných je označení předpokládaného typu (type hint) přiřazované hodnoty při deklaraci proměnné. Protože je Python dynamicky typovaný jazyk, je tato informace pro jeho interpreta zcela nezávazná. Slouží téměř výhradně k lepšímu chápání smyslu uživatelem čteného skriptu. Pomáhá při ladění kódu například pomocí aplikace mypy.
    Náznakem typu lze opatřit deklaraci proměnné, parametry a vratnou hodnotu funkce, jakož i metody třídy.

    Používaná skladba náznaků

    Náznak typu proměnné:       name: type
    Totéž s přiřazením hodnoty: name: type = value 
    
    Náznaky u parametrů funkce: def func_name(a: type, b: type):
    u výstupní hodnoty funkce:  def func_name(a: type, b: type): -> type:
    
    Totéž platí pro metody, t.j. funkce, definované uvnitř třídy,
    včetně iniciační metody __init__. 
    

    Jako příklad si uveďme definici funkce, potvrzující pravdivost druhé věty úvodního odstavce:

    # F:/Codetest/HowTopy/ch-02
    
    def multi(a: int, b: int, x) -> str:
        return (a + b) * x
    
    print(multi(2.5, 7, 3))	         # --> 28.5
    print(multi('ha', 'ló ', 2))     # --> haló haló	
    

    Interpret Pythonu náš předpis v pohodě ignoroval, protože ví, jak provádět součet a násobení a že tyto operace lze realizovat pro čísla i řetězce.
    Pokud bychom tuto funkci realizovali pod dohledem aplikace mypy, dostalo by se nám v Terminálu těchto informací:

    F:\Codetest\HowTopy\ch-02> mypy annot_meth.py
    
    annot_meth.py:5: error: Argument 1 to "multi"
     has incompatible type "str"; expected "int"  [arg-type]
    annot_meth.py:5: error: Argument 2 to "multi"
     has incompatible type "str"; expected "int"  [arg-type]
    annot_meth.py:6: error: Argument 1 to "multi"
     has incompatible type "float"; expected "int"  [arg-type]
    Found 3 errors in 1 file (checked 1 source file)
    

    Aplikaci mypy si do Pythonu nainstalujeme příkazem > pip install mypy.


    2.8 Glosář

    hodnota (value)
    Objekt (číslo, řetězec, atp), přiřazený k proměnné nebo zadaný jako argument funkce.
    typ (type)
    Typ objektu určuje jak může být objekt ve výrazech použit. Je to název třídy, z níž byl objekt odvozen.
    int (integer)
    Datový typ Pythonu pro kladná a záporná celá čísla.
    str (string)
    Datový typ Pythonu pro řetězce alfanumerických znaků.
    float
    Datový typ Pythonu pro čísla s plovoucí desetinnou čárkou. Interně se tato čísla skládají ze dvou částí: z báze a exponentu. Kvůli chybě při zaokrouhlování jde o číslo s přibližnou hodnotou.
    proměnná (variable)
    Jméno, které odkazuje na hodnotu.
    příkaz přířazení (assignment statement)
    Příkaz, který jménu (proměnné) přiřadí hodnotu. Na levé straně operátoru přiřazení (=) je jméno. Na pravé straně operátoru je hodnota nebo výraz, který je interpretem Pythonu nejprve vyhodnocen a potom přiřazem jménu.
    klíčové slovo (keyword)
    Vyhrazené jméno předdefinovaného objektu; klíčová slova jako if, def, a while nemůžeme použít jako jména proměnných.
    operátor (operator)
    Speciální symbol (+ - * /) , stojící mezi svými operandy.
    operand (operand)
    Jedna z hodnot, s nimiž operátor pracuje.
    výraz (expression)
    Kombinace proměnných, operátorů a hodnot, které lze vyjádřit výslednou hodnotou.
    funkce
    Pojmenovaný blok příkazů, provádějící nějakou operaci, či řadu navazujících operací.
    skladba (composition)
    Spojení jednoduchých výrazů a příkazů do složených příkazů a výrazů za účelem stručnější prezentace složitých výpočtů.
    vyhodnocení (evaluation)
    Zjednodušení výrazu provedením zadaných operací, které jsou tak nahrazeny jedinou hodnotou.

    2.9 Cvičení

    1. Co se stane, když dáte příkaz k tisku přiřazení?
      >>> print(n = 7)
      
      A což toto?
      >>> print(7 + 5)
      
      Nebo toto?
      >>> print(5.2, "toto", 4-2, 5/2.0)
      
    2. Následující číselné výrazy vypočítejte z hlavy a výsledky si následně ověřte v konzole:
      >>>  5 % 2
      >>>  9 % 5
      >>>  15 % 12
      >>>  12 % 15
      >>>  6 % 6
      >>>  0 % 7
      >>>  7 % 0
      
    3. Přidejte závorky k výrazu 6 * 1 - 2 tak, aby se změnila jeho hodnota ze 4 na -6.
    4. Za prompt v konzole Pythonu zapište houby + 4. To vyvolá chybu:
      NameError: name 'houby' is not defined
      
      Jménu houby přiřaďte takovou hodnotu, aby houby + 4 bylo 10.
    5. Dovedl byste zapsat následující vzorec pro výpočet výsledné hodnoty A počátečního vkladu P jako výraz v programovém jazyce Python?
      kde:
      • P = počáteční vklad
      • r = úroková míra per annum jako desetinné číslo
      • n = počet hodnocených období za rok
      • t = počet roků
      Pro P=10000 Kč, n=12 měsíců, r=8%(0,08) a t=10 let by hodnota A měla být přibližně 22196.4 Kč.

      Úlohu řešte v interaktivním i programovém režimu v aplikaci IDLE. Skript vložte do souboru vynos.py ve složce kap-02.

    6. Každé slovo věty All work and no play makes Jack a dull boy připojte hromadným přiřazením k vlastní proměnné a potom větu vytiskněte na jeden řádek s použitím funkce print().

    prev up next title end end