@@ -32,6 +32,7 @@ Objekty spojují data a funkčnost dohromady.
32
32
> Funkce ` len ` ale funguje i na
33
33
> objektech, které s řetězci nemají nic společného.
34
34
35
+
35
36
# Třídy
36
37
37
38
Data každého objektu jsou specifická pro konkrétní
@@ -57,8 +58,8 @@ Tohle společné chování určuje
57
58
* typ* (angl. * type* ) neboli * třída* (angl. * class* ) daného objektu.
58
59
59
60
> [ note]
60
- > V historických verzích Pythonu byl rozdíl mezi „typem“
61
- > a „třídou“, ale dnes už jsou to synonyma.
61
+ > V jiných jazycích než Python 3 můžou slova „typ“ a „třída“ označovat různé
62
+ > věci. Pro nás to budou synonyma.
62
63
63
64
Typ objektu umí zjistit funkce ` type ` :
64
65
@@ -75,9 +76,14 @@ Typ objektu umí zjistit funkce `type`:
75
76
<class '_io.TextIOWrapper'>
76
77
```
77
78
78
- Takže ` type ` vrací nějaké třídy.
79
- A co je to třída? Popis, jak se chovají všechny objekty
80
- daného typu.
79
+ A co je to třída? Třída je * popis* , jak se všechny objekty
80
+ daného typu chovají.
81
+
82
+ Například ` <class 'int'> ` obsahuje všechno, co je společné všem celým číslům:
83
+ že (a jak) se dají sčítat, jak takové číslo převést na řetězec, a tak dále.
84
+
85
+
86
+ ## Tvoření objektů třídy
81
87
82
88
Většinu tříd jde navíc v Pythonu zavolat, jako by
83
89
to byly funkce, a vytvořit tak nový objekt dané třídy:
@@ -95,7 +101,7 @@ Chová se to stejně jako funkce `str`! Není to podivné?
95
101
Tady se musím omluvit:
96
102
[ materiály k funkcím] ( ../functions/ )
97
103
tak trochu lhaly. Funkce ` str ` , ` int ` , ` float ` apod. totiž vůbec
98
- nejsou funkce – jsou to právě třídy.
104
+ nejsou funkce – jsou to právě třídy:
99
105
100
106
``` pycon
101
107
>>> str
108
114
109
115
Ale dají se, podobně jako funkce, zavolat.
110
116
Třída tedy většinou obsahuje nejen „popis“, jak se
111
- objekty daného typu budou chovat, ale umí i objekty
112
- daného typu vytvořit.
117
+ její objekty budou chovat, ale „umí“ takové objekty i vytvořit.
113
118
114
119
## Vlastní třídy
115
120
@@ -133,8 +138,7 @@ class Kotatko:
133
138
134
139
Tak jako se funkce definují pomocí ` def ` ,
135
140
třídy mají klíčové slovo ` class ` ,
136
- za které napíšeš jméno třídy, dvojtečku,
137
- a pak odsazené tělo třídy.
141
+ za které napíšeš jméno třídy, dvojtečku a pak odsazené tělo třídy.
138
142
Podobně jako ` def ` dělá funkce, příkaz
139
143
` class ` udělá novou třídu a přiřadí ji
140
144
do proměnné daného jména (tady ` Kotatko ` ).
@@ -148,8 +152,8 @@ aby se nepletly s „normálními“ hodnotami.
148
152
> důvodů – původně to byly opravdu funkce.
149
153
150
154
V těle třídy můžeš definovat metody, které vypadají
151
- úplně jako funkce – jen mají první argument ` self ` .
152
- Ten si ale vysvětlíme později – zamňoukání má přednost :
155
+ úplně jako funkce – jen mají první parametr ` self ` .
156
+ Ten si ale vysvětlíme později – napřed zkus zamňoukat :
153
157
154
158
``` python
155
159
# Vytvoření konkrétního objektu
@@ -161,22 +165,28 @@ kotatko.zamnoukej()
161
165
162
166
V tomhle příkladu si dej pozor na velikost písmen:
163
167
` Kotatko ` (s velkým K) je třída – popis, jak
164
- se koťátka chovají. ` kotatko ` (s malým k)
168
+ se koťátka chovají.
169
+ ` kotatko ` (s malým k)
165
170
je konkrétní objekt (angl. * instance* ) té třídy:
166
171
hodnota, která reprezentuje kotě.
167
- Onen konkrétní objekt vytvoříme zavoláním třídy,
168
- stejně jako zavoláním ` str() ` se dá vytvořit
169
- konkrétní řetězec.
172
+
173
+ Když definuješ třídu (pomocí bloku ` class ` ), neznamená to zatím, že ve tvém
174
+ programu je nějaké koťátko.
175
+ Třída je jako recept nebo manuál: když si koupíš kuchařku, budeš teoreticky
176
+ vědět jak upéct dort, jak bude takový dort vypadat a že se dá sníst.
177
+ Ale neznamená to ještě, že máš samotný dort!
178
+
179
+ Konkrétní objekt vytvoříš až zavoláním třídy.
180
+ Stejně jako zavoláním ` str() ` se dá vytvořit konkrétní řetězec,
181
+ volání ` Kotatko() ` vytvoří nový objekt tvé třídy, který už můžeš použít.
170
182
171
183
Mňau!
172
184
173
185
## Atributy
174
186
175
- Objekty vytvořené z „vlastních“ tříd mají jednu
176
- vlastnost, kterou třídy jako ` str `
177
- nedovolují: možnost si definovat vlastní
178
- * atributy* – informace, které se uloží k danému
179
- objektu.
187
+ Objekty vytvořené z „vlastních“ tříd mají funkčnost, kterou třídy jako ` str `
188
+ nedovolují: máš možnost si definovat vlastní
189
+ * atributy* – informace, které se uloží k danému objektu.
180
190
Atributy se označují tak, že mezi hodnotu a jméno
181
191
jejího atributu napíšeš tečku:
182
192
@@ -193,9 +203,9 @@ print(micka.jmeno)
193
203
194
204
Na začátku jsme si řekl{{gnd('i', 'y', both='i')}}, že objekty spojují chování
195
205
a data.
196
- Chování je definováno ve třídě, data se schovávají
197
- právě v atributech jednotlivých objektů.
198
- Podle atributů jako jméno můžeš jednotlivá koťátka
206
+ Chování je definováno ve třídě; data se schovávají
207
+ právě v atributech jednotlivých objektů.
208
+ Podle atributů jako ` jmeno ` pak můžeš jednotlivá koťátka
199
209
rozlišit.
200
210
201
211
> [ note]
@@ -213,18 +223,17 @@ rozlišit.
213
223
214
224
# # Parametr `self`
215
225
216
- A teď se na chvíli vrátíme k metodám,
217
- konkrétně k parametru `self ` .
226
+ Teď se na chvíli vraťme k metodám. Konkrétně k parametru `self ` .
218
227
219
228
Každá metoda má přístup ke konkrétnímu objektu, na
220
229
kterém pracuje, právě přes argument `self ` .
221
- Teď, když máš koťátka pojmenovaná,
222
- můžeš pomocí ` self ` rozjet dialog :
230
+ Teď, když máš koťátka pojmenovaná, můžeš v metodě `zamnoukej` použít ` self `
231
+ a dostat se tak ke jménu daného koťátka :
223
232
224
233
```python
225
234
class Kotatko :
226
235
def zamnoukej (self ):
227
- print (" { } : Mňau!" .format( self .jmeno) )
236
+ print (f " { self .jmeno } : Mňau! " )
228
237
229
238
mourek = Kotatko()
230
239
mourek.jmeno = ' Mourek'
@@ -236,32 +245,27 @@ mourek.zamnoukej()
236
245
micka.zamnoukej()
237
246
```
238
247
239
- Co se stalo? Výraz ` mourek.zamnoukej ` udělá * metodu* , která, když ji zavoláš,
240
- předá objekt ` mourek ` jako první argument
241
- funkce ` zamnoukej ` .
248
+ Co se stalo? Výraz ` mourek.zamnoukej ` udělá * metodu* .
249
+ Když ji pak zavoláš ( ` mourek.zamnoukej() ` ),
250
+ objekt ` mourek ` se předá funkci ` zamnoukej ` jako první argument, ` self ` .
242
251
243
252
> [ note]
244
- > Tohle je to, čím se * metoda* liší od normální * funkce* :
245
- > metoda si „pamatuje“ objekt, na kterém pracuje.
246
-
247
- A takový první argument, který obsahuje konkrétní
248
- objekt právě definované třídy, se tradičně pojmenovává ` self ` .
249
- (Když ho pojmenuješ jinak, ostatní programátoři se na tebe budou koukat hodně
250
- divně.)
253
+ > Onen první argument metody můžeš teoreticky pojmenovat i jinak než ` self ` ,
254
+ > ale když to uděláš, ostatní programátoři se na tebe budou koukat hodně divně.
251
255
252
256
253
- A může taková metoda brát víc než jeden argument?
257
+ Může taková metoda brát víc než jeden argument?
254
258
Může – ` self ` se doplní na první místo,
255
- a zbytek argumentů se vezme z volání metody.
259
+ zbytek argumentů se vezme z volání metody.
256
260
Třeba:
257
261
258
262
``` python
259
263
class Kotatko :
260
264
def zamnoukej (self ):
261
- print (" { } : Mňau!" .format( self .jmeno) )
265
+ print (f " { self .jmeno } : Mňau! " )
262
266
263
267
def snez (self , jidlo ):
264
- print (" { } : Mňau mňau! {} mi chutná!" .format( self .jmeno, jidlo) )
268
+ print (f " { self .jmeno } : Mňau mňau! { jidlo } mi chutná! " )
265
269
266
270
mourek = Kotatko()
267
271
mourek.jmeno = ' Mourek'
@@ -270,48 +274,64 @@ mourek.snez('ryba')
270
274
271
275
## Metoda ` __init__ `
272
276
273
- A když jsme u argumentů, je ještě jedno místo,
274
- kde můžeš třídě poslat argumenty: když vytváříš
275
- nový objekt (voláním třídy).
276
- Dá se tak hezky vyřešit problém, který možná vidíš
277
- v předchozím kódu: aktuálně každé koťátko potřebuje,
278
- aby se mu po vytvoření nastavilo jméno, jinak
279
- metoda ` zamnoukej ` nebude fungovat.
280
- Třída se ale dá udělat i tak, že půjde jméno nastavit
281
- už při vytváření, takhle:
277
+ Co se stane, když koťátku zapomeneš nastavit jméno?
278
+ Metoda ` zamnoukej ` přestane fungovat:
279
+
280
+ ``` pycon
281
+ >>> micka = Kotatko()
282
+ >>> micka.snez(' ryba' )
283
+ Traceback (most recent call last):
284
+ File "<zvirata.py>", line 5, in snez
285
+ AttributeError: 'Kotatko' object has no attribute 'jmeno'
286
+ ```
287
+
288
+ Aby tahle chyba nemohla nastat, můžeš zařídit, aby každé kotě * muselo* být
289
+ pojmenované – a to už od okamžiku kdy vznikne.
290
+ Jméno pak budeš zadávat už při vytváření kotěte, nějak takhle:
282
291
283
292
``` python
284
293
mourek = Kotatko(jmeno = ' Mourek' )
285
294
```
286
295
287
- Na tohle používá Python metodu,
288
- která se jmenuje ` __init__ ` (dvě podtržítka,
296
+ To ale zatím nefunguje; musíš na to třídu ` Kotatko ` připravit.
297
+
298
+ Použij na to speciální metodu, která se jmenuje ` __init__ ` (dvě podtržítka,
289
299
` init ` , dvě podtržítka).
290
300
To „opodtržítkování“ znamená, že tohle jméno je nějakým způsobem speciální.
291
- Metoda ` __init__ ` se totiž zavolá
292
- automaticky, když se vytvoří nový objekt.
293
- Dá se tedy napsat:
301
+ Metodu ` __init__ ` totiž Python zavolá
302
+ automaticky, když vytvoří nový objekt.
303
+ Můžeš tedy napsat:
294
304
295
305
``` python
296
306
class Kotatko :
297
307
def __init__ (self , jmeno ):
298
308
self .jmeno = jmeno
299
309
300
310
def zamnoukej (self ):
301
- print (" { } : Mňau!" .format( self .jmeno) )
311
+ print (f " { self .jmeno } : Mňau! " )
302
312
303
313
def snez (self , jidlo ):
304
- print (" { } : Mňau mňau! {} mi chutná!" .format( self .jmeno, jidlo) )
314
+ print (f " { self .jmeno } : Mňau mňau! { jidlo } mi chutná! " )
305
315
306
316
mourek = Kotatko(' Mourek' )
307
317
mourek.zamnoukej()
308
318
```
309
319
310
- A teď už není možnost, jak vytvořit koťátko bez jména,
311
- takže ` zamnoukej ` bude vždycky fungovat.
320
+ A teď už není možnost, jak vytvořit koťátko beze jména.
321
+ Metoda ` zamnoukej ` bude vždycky fungovat.
322
+
323
+ Jako u jiných funkcí je možné jméno koťátka zadat buď jako pojmenovaný
324
+ argument, nebo jako poziční. Obojí funguje stejně:
325
+
326
+ ```
327
+ mourek = Kotatko('Mourek') # 'Mourek' je hodnota prvního argument pro __init__ (po self)
328
+ micka = Kotatko(jmeno='Micka') # 'Micka' je hodnota argumentu `jmeno`
329
+ ```
330
+
331
+ ### Metoda ` __str__ `
312
332
313
- Podobných „opodtržítkovaných“ metod je víc,
314
- třeba ` __str__ ` se volá , když je potřeba
333
+ Podobných „opodtržítkovaných“ (speciálních) metod je víc.
334
+ Třeba metodu ` __str__ ` Python zavolá , když je potřeba
315
335
převést objekt na řetězec:
316
336
317
337
``` python
@@ -320,60 +340,18 @@ class Kotatko:
320
340
self .jmeno = jmeno
321
341
322
342
def __str__ (self ):
323
- return ' <Kotatko jmenem {} > ' .format( self .jmeno)
343
+ return f ' <Kotatko jmenem { self .jmeno} > '
324
344
325
345
def zamnoukej (self ):
326
- print (" { } : Mňau!" .format( self .jmeno) )
346
+ print (f " { self .jmeno } : Mňau! " )
327
347
328
348
def snez (self , jidlo ):
329
- print (" { } : Mňau mňau! {} mi chutná!" .format( self .jmeno, jidlo) )
349
+ print (f " { self .jmeno } : Mňau mňau! { jidlo } mi chutná! " )
330
350
331
351
mourek = Kotatko(' Mourek' )
332
352
print (mourek)
333
353
```
334
354
335
- ## Cvičení: Kočka
336
-
337
- Teď, když už umíš dělat koťátka, zkus vytvořit třídu pro kočku.
338
-
339
- - Kočka umí mňoukat metodou ` zamnoukej ` .
340
- - Kočka má na začátku (při vytvoření) 9 životů
341
- (nemůže mít nikdy víc než 9 nebo míň než 0!).
342
- - Kočka umí říct, jestli je živá (nemá 0 životů), metodou ` je_ziva ` .
343
- - Kočka může ztratit život metodou ` uber_zivot ` .
344
- - Kočku můžeš nakrmit metodou ` snez ` , která bere 1 argument -
345
- nějaké konkrétní jídlo (řetězec). Pokud je toto jídlo ` "ryba" ` , kočce se obnoví
346
- jeden život (pokud teda už není mrtvá, nebo nemá maximální počet životů).
347
-
348
- {% filter solution %}
349
- ``` python
350
- class Kocka :
351
- def __init__ (self ): # Init funkce nemusi brat jako parametr
352
- self .pocet_zivotu = 9 # pocet zivotu, ten je pokazde 9.
353
-
354
- def zamnoukej (self ):
355
- print (" Mnau, mnau, mnauuu!" )
356
-
357
- def je_ziva (self ):
358
- return self .pocet_zivotu > 0
359
-
360
- def uber_zivot (self ):
361
- if not self .je_ziva():
362
- print (" Nemuzes zabit uz mrtvou kocku!" )
363
- else :
364
- self .pocet_zivotu -= 1
365
-
366
- def snez (self , jidlo ):
367
- if not self .je_ziva():
368
- print (" Je zbytecne krmit mrtvou kocku!" )
369
- return
370
- if jidlo == " ryba" and self .pocet_zivotu < 9 :
371
- self .pocet_zivotu += 1
372
- print (" Kocka spapala rybu a obnovil se ji jeden zivot." )
373
- else :
374
- print (" Kocka se krmi." )
375
- ```
376
- {% endfilter %}
377
355
378
356
A to je o samotných třídách zatím vše.
379
357
[ Příště] ( ../inheritance/ ) si něco řekneme o dědičnosti.
0 commit comments