12 |
13 |
14 | Python
15 | 17.03.2015
16 |
17 |
18 |
19 |
20 |
21 |
22 | Кирил Владимиров
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Python 101
49 |
50 |
51 |
52 | - general-purpose
53 |
54 | - high-level
55 |
56 | - object-oriented
57 |
58 | - a bit functional
59 |
60 | - ...
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | Къде отива кодът?
72 |
73 |
74 |
75 | - Код се пише в
.py файлове (например gameoflife.py).
76 |
77 | - Изпълнява се с
python gameoflife.py
78 |
79 | - Можем да пишем код интерактивно, като пуснем python без аргументи.
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | Python е предсказуем
91 |
92 |
93 |
94 | Когато не сте сигурни, просто пробвайте.
95 |
96 |
97 |
98 |
99 | $ python
100 | >>> 5 + 10
101 | 15
102 | >>> a = 5
103 | >>> b = a + 10
104 | >>> print(b)
105 | 15
106 | >>> a * 2
107 | 10
108 | >>> a ** 2
109 | 25
110 | >>> "hello" + ', ' + "world"
111 | "hello, world"
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | Един ред код
122 |
123 |
124 | my_var = 'spam'.upper()
125 | print(my_var) # SPAM
126 |
127 |
128 |
129 |
130 | - Съдържа един израз, никога не завършва с ;
131 |
132 | - Всичко след # е коментар
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | Имена
144 |
145 |
146 |
147 | Можем да дадем име на стойност и получаваме променлива:
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | Динамичен език - стойностите имат тип, но имената - не.
158 |
159 |
160 |
161 |
162 | а = 5
163 | type(a) # <class 'int'>
164 | a = 'test'
165 | type(a) # <class 'str'>
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | Имена
176 |
177 |
178 |

179 |
180 |
181 |
182 |

183 |
184 |
185 |
186 |

187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | Duck-typing
197 | When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck
198 |
199 | class Duck:
200 | def quack(self):
201 | print("Quack, quack!")
202 |
203 | def fly(self):
204 | print("Flap, Flap!")
205 |
206 | class Person:
207 | def quack(self):
208 | print("I'm Quackin'!")
209 |
210 | def fly(self):
211 | print("I'm Flyin'!")
212 |
213 | def in_the_forest(mallard):
214 | mallard.quack()
215 | mallard.fly()
216 |
217 | in_the_forest(Duck())
218 | in_the_forest(Person())
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 | Всичко е обект
229 |
230 |
231 |
232 | Буквално
233 |
234 |
235 |
236 |
237 | >>> type(42)
238 | <class 'int'>
239 | >>> type([])
240 | <class 'list'>
241 | >>> type([]) is list
242 | True
243 | >>> type(list)
244 | <class 'type'>
245 | >>> type(list) is type
246 | True
247 | >>> type(type(type(list)))
248 | <class 'type'>
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 | Класове
259 |
260 |
261 | class Vector:
262 | def __init__(self, x, y):
263 | self.x = x
264 | self.y = y
265 |
266 | v = Vector(1.0, 1.0)
267 |
268 |
269 |
270 |
271 | - Атрибутите не се нуждаят от декларации
272 |
273 | - Винаги са достъпни
274 |
275 | - Могат да се променят
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 | private/protected
287 |
288 |
289 |
290 | - private и protected концепциите не са това, за което сте свикнали да мислите в езици като C++/Java/C#
291 |
292 | - Ограниченията за използване на защитени и частни методи в класовете в python е отговорност на програмиста
293 |
294 | - Атрибути започващи с _ са защитени, т.е. би следвало да се ползват само от методи на класа и наследяващи го класове
295 |
296 | - Атрибути започващи с са частни, т.е. би следвало да се ползват само от методи на класа
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 | "би следвало"
308 |
309 |
310 |
311 | Нищо не ви пречи да ги достъпвате
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 | Константи
323 |
324 |
325 |
326 | - Имената им са в
SCREAMING_SNAKE_CASE
327 |
328 | - Също чисто конвенционални
329 |
330 | - Можете да ги промените и нищо няма да ви спре
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 | Методи
342 |
343 |
344 |
345 | Те са си атрибути като всички други
346 |
347 |
348 |
349 |
350 |
351 | - Могат да се достъпват
352 |
353 | - Могат да се променят
354 |
355 | - Могат и да се добавят нови, по време на изпълнение
356 |
357 |
358 |
359 |
360 | v = Vector(1.0, 1.0)
361 | Vector.inject = lambda _: print("EVIL!!!!")
362 | v.inject()
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 | Достъп до всичко
373 |
374 |
375 |
376 | - Всеки обект си има
__dict__ със всички атрибути
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 | Можем да се предпазим от това
388 |
389 |
390 |
391 | __slots__
392 |
393 |
394 |
395 |
396 | class Vector:
397 | __slots__ = 'x', 'y'
398 |
399 | v = Vector()
400 | v.x = 1
401 | v.y = 2
402 | v.z = 3
403 | ---------------------------------------------------------------------------
404 | AttributeError Traceback (most recent call last)
405 | <ipython-input-20-8460e7b49cf0> in <module>()
406 | ----> 1 v.z = 3
407 |
408 | AttributeError: 'Vector' object has no attribute 'z'
409 |
410 |
411 |
412 |
413 | - По-компактни обекти
414 |
415 | - Контрол над атрибутите
416 |
417 | - Идеални, ако правите много от тях
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 | Достъпване от потребителски вход
429 |
430 |
431 |
432 | Можем и да правим и така:
433 |
434 |
435 |
436 |
437 | getattr(v, some_str_from_the_stdin)
438 |
439 |
440 |
441 |
442 | Внимавайте с това
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 | Магически методи
454 |
455 |
456 |
457 | - __add__(self, other) за self + other
458 |
459 | - __sub__(self, other) за self - other
460 |
461 | - __mul__(self, other) за self * other
462 |
463 | - __truediv__(self, other) за self / other
464 |
465 | - __floordiv__(self, other) за self // other
466 |
467 | - __mod__(self, other) за self % other
468 |
469 | - __lshift__(self, other) за self << other
470 |
471 | - __rshift__(self, other) за self >> other
472 |
473 | - __and__(self, other) за self & other
474 |
475 | - __xor__(self, other) за self ^ other
476 |
477 | - __or__(self, other) за self | other
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 | GC
489 |
490 |
491 |
492 | - reference counting
493 |
494 | - Може да се справя с циклите... почти винаги
495 |
496 | - Можете да дефинирате _finalizer_-и на вашите обекти с
__del__
497 |
498 | - Ако обекти с дефинирани _finalizer_-и зациклят, интерпретаторът вдига ръце
499 |
500 | - Можете да си ги чистите сами... ако се сетите
501 |
502 | - Което едва ли ще стане, преди това да е проблем
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 | Concurrency
514 |
515 |
516 |
517 | И в Python има GIL
518 |
519 |
520 |
521 |
522 |
523 | - Подходящ за I/O bound проблеми
524 |
525 | - Крайно неподходящ за CPU bound такива
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 | Parallelism
537 |
538 |
539 |
540 | Само с нови процеси
541 |
542 |
543 |
544 |
545 |
546 | - multiprocessing
547 |
548 | - subproccess
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 | subproccess.call
560 |
561 |
562 |
563 | В никакъв случай не му подавайте shell=True, ако има потребителски вход
564 |
565 |
566 |
567 |
568 | >>> from subprocess import call
569 | >>> filename = input("What file would you like to display?\n")
570 | What file would you like to display?
571 | non_existent; rm -rf / #
572 | >>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 | Thank you
582 |
583 |
584 |
585 |
586 |
587 | Кирил Владимиров
588 |
589 |
590 |
591 |
592 |
593 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 | Use the left and right arrow keys or click the left and right
619 | edges of the page to navigate between slides.
620 | (Press 'H' or navigate to hide this message.)
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |