python.md

Личный сайт Go-разработчика из Казани

Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из самых популярных языков. Я влюбился в Python за понятный и доходчивый синтаксис — это почти что исполняемый псевдокод.

1# Однострочные комментарии начинаются с символа решётки. 2 3""" Многострочный текст может быть 4 записан, используя 3 знака " и обычно используется 5 в качестве встроенной документации 6""" 7 8#################################################### 9## 1. Примитивные типы данных и операторы 10#################################################### 11 12# У вас есть числа 133 # => 3 14 15# Математика работает вполне ожидаемо 161 + 1 # => 2 178 - 1 # => 7 1810 * 2 # => 20 1935 / 5 # => 7.0 20 21# Результат целочисленного деления округляется в меньшую сторону 22# как для положительных, так и для отрицательных чисел. 235 // 3 # => 1 24-5 // 3 # => -2 255.0 // 3.0 # => 1.0 # работает и для чисел с плавающей запятой 26-5.0 // 3.0 # => -2.0 27 28# Результат деления возвращает число с плавающей запятой 2910.0 / 3 # => 3.3333333333333335 30 31# Остаток от деления 327 % 3 # => 1 33 34# Возведение в степень 352**3 # => 8 36 37# Приоритет операций указывается скобками 381 + 3 * 2 # => 7 39(1 + 3) * 2 # => 8 40 41# Булевы значения - примитивы (Обратите внимание на заглавную букву) 42True # => True 43False # => False 44 45# Для отрицания используется ключевое слово not 46not True # => False 47not False # => True 48 49# Булевы операторы 50# Обратите внимание: ключевые слова "and" и "or" чувствительны к регистру букв 51True and False # => False 52False or True # => True 53 54# True и False на самом деле 1 и 0, но с разными ключевыми словами 55True + True # => 2 56True * 8 # => 8 57False - 5 # => -5 58 59# Операторы сравнения обращают внимание на числовое значение True и False 600 == False # => True 611 == True # => True 622 == True # => False 63-5 != False # => True 64 65# Использование булевых логических операторов на типах int превращает их в булевы значения, но возвращаются оригинальные значения 66# Не путайте с bool(ints) и bitwise and/or (&,|) 67bool(0) # => False 68bool(4) # => True 69bool(-6) # => True 700 and 2 # => 0 71-5 or 0 # => -5 72 73# Равенство — это == 741 == 1 # => True 752 == 1 # => False 76 77# Неравенство — это != 781 != 1 # => False 792 != 1 # => True 80 81# Ещё немного сравнений 821 < 10 # => True 831 > 10 # => False 842 <= 2 # => True 852 >= 2 # => True 86 87# Проверка, находится ли значение в диапазоне 881 < 2 and 2 < 3 # => True 892 < 3 and 3 < 2 # => False 90 91# Сравнения могут быть записаны цепочкой 921 < 2 < 3 # => True 932 < 3 < 2 # => False 94 95# (is vs. ==) ключевое слово is проверяет, относятся ли две переменные к одному и тому же объекту, но == проверяет если указанные объекты имеют одинаковые значения. 96a = [1, 2, 3, 4] # a указывает на новый список, [1, 2, 3, 4] 97b = a # b указывает на то, что указывает a 98b is a # => True, a и b относятся к одному и тому же объекту 99b == a # => True, Объекты a и b равны 100b = [1, 2, 3, 4] # b указывает на новый список, [1, 2, 3, 4] 101b is a # => False, a и b не относятся к одному и тому же объекту 102b == a # => True, Объекты a и b равны 103 104# Строки определяются символом " или ' 105"Это строка." 106'Это тоже строка.' 107 108# И строки тоже могут складываться! 109"Привет " + "мир!" # => "Привет мир!" 110 111# Строки (но не переменные) могут быть объединены без использования '+' 112"Привет " "мир!" # => "Привет мир!" 113 114# Со строкой можно работать, как со списком символов 115"Привет мир!"[0] # => 'П' 116 117# Вы можете найти длину строки 118len("Это строка") # => 10 119 120# Вы также можете форматировать, используя f-строки (в Python 3.6+) 121name = "Рейко" 122f"Она сказала, что ее зовут {name}." # => "Она сказала, что ее зовут Рейко" 123# Вы можете поместить любой оператор Python в фигурные скобки, и он будет выведен в строке. 124f"{name} состоит из {len(name)} символов." # => "Рэйко состоит из 5 символов." 125 126 127# None является объектом 128None # => None 129 130# Не используйте оператор равенства "==" для сравнения 131# объектов с None. Используйте для этого "is" 132"etc" is None # => False 133None is None # => True 134 135# None, 0 и пустые строки/списки/словари/кортежи приводятся к False. 136# Все остальные значения равны True 137bool(0) # => False 138bool("") # => False 139bool([]) # => False 140bool({}) # => False 141bool(()) # => False 142 143 144#################################################### 145## 2. Переменные и Коллекции 146#################################################### 147 148# В Python есть функция Print 149print("Я Python. Приятно познакомиться!") # => Я Python. Приятно познакомиться! 150 151# По умолчанию, функция print() также выводит новую строку в конце. 152# Используйте необязательный аргумент end, чтобы изменить конец последней строки. 153print("Привет мир", end="!") # => Привет мир! 154 155# Простой способ получить входные данные из консоли 156input_string_var = input("Введите данные: ") # Возвращает данные в виде строки 157# Примечание: в более ранних версиях Python метод input() назывался raw_input() 158 159# Объявлять переменные перед инициализацией не нужно. 160# По соглашению используется нижний_регистр_с_подчёркиваниями 161some_var = 5 162some_var # => 5 163 164# При попытке доступа к неинициализированной переменной выбрасывается исключение. 165# Об исключениях см. раздел "Поток управления и итерируемые объекты". 166some_unknown_var # Выбрасывает ошибку NameError 167 168# if можно использовать как выражение 169# Эквивалент тернарного оператора '?:' в C 170"да!" if 0 > 1 else "нет!" # => "нет!" 171 172# Списки хранят последовательности 173li = [] 174# Можно сразу начать с заполненного списка 175other_li = [4, 5, 6] 176 177# Объекты добавляются в конец списка методом append() 178li.append(1) # [1] 179li.append(2) # [1, 2] 180li.append(4) # [1, 2, 4] 181li.append(3) # [1, 2, 4, 3] 182# И удаляются с конца методом pop() 183li.pop() # => возвращает 3 и li становится равен [1, 2, 4] 184# Положим элемент обратно 185li.append(3) # [1, 2, 4, 3]. 186 187# Обращайтесь со списком, как с обычным массивом 188li[0] # => 1 189 190# Обратимся к последнему элементу 191li[-1] # => 3 192 193# Попытка выйти за границы массива приведёт к ошибке индекса 194li[4] # Выбрасывает ошибку IndexError 195 196# Можно обращаться к диапазону, используя так называемые срезы 197# (Для тех, кто любит математику, это называется замкнуто-открытый интервал). 198li[1:3] # Вернуть список из индекса с 1 по 3 => [2, 4] 199li[2:] # Вернуть список, начиная с индекса 2 => [4, 3] 200li[:3] # Вернуть список с начала до индекса 3 => [1, 2, 4] 201li[::2] # Вернуть список, выбирая каждую вторую запись => [1, 4] 202li[::-1] # Вернуть список в обратном порядке => [3, 4, 2, 1] 203# Используйте сочетания всего вышеназванного для выделения более сложных срезов 204# li[начало:конец:шаг] 205 206# Сделать однослойную глубокую копию, используя срезы 207li2 = li[:] # => li2 = [1, 2, 4, 3], но (li2 is li) вернет False. 208 209# Удаляем произвольные элементы из списка оператором del 210del li[2] # [1, 2, 3] 211 212# Удалить первое вхождение значения 213li.remove(2) # [1, 3] 214li.remove(2) # Выбрасывает ошибку ValueError поскольку 2 нет в списке 215 216# Вставить элемент по определенному индексу 217li.insert(1, 2) # [1, 2, 3] 218 219# Получить индекс первого найденного элемента, соответствующего аргументу 220li.index(2) # => 1 221li.index(4) # Выбрасывает ошибку ValueError поскольку 4 нет в списке 222 223# Вы можете складывать, или, как ещё говорят, конкатенировать списки 224# Обратите внимание: значения li и other_li при этом не изменились. 225li + other_li # => [1, 2, 3, 4, 5, 6] 226 227# Объединять списки можно методом extend() 228li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6] 229 230# Проверить элемент на наличие в списке можно оператором in 2311 in li # => True 232 233# Длина списка вычисляется функцией len 234len(li) # => 6 235 236 237# Кортежи похожи на списки, только неизменяемые 238tup = (1, 2, 3) 239tup[0] # => 1 240tup[0] = 3 # Выбрасывает ошибку TypeError 241 242# Обратите внимание, что кортеж длины 1 должен иметь запятую после последнего элемента, но кортежи другой длины, даже 0, не должны. 243type((1)) # => <class 'int'> 244type((1,)) # => <class 'tuple'> 245type(()) # => <class 'tuple'> 246 247# Всё то же самое можно делать и с кортежами 248len(tup) # => 3 249tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) 250tup[:2] # => (1, 2) 2512 in tup # => True 252 253# Вы можете распаковывать кортежи (или списки) в переменные 254a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3 255# Вы также можете сделать расширенную распаковку 256a, *b, c = (1, 2, 3, 4) # a теперь 1, b теперь [2, 3] и c теперь 4 257# Кортежи создаются по умолчанию, если опущены скобки 258d, e, f = 4, 5, 6 # кортеж 4, 5, 6 распаковывается в переменные d, e и f 259# соответственно, d = 4, e = 5 и f = 6 260# Обратите внимание, как легко поменять местами значения двух переменных 261e, d = d, e # теперь d == 5, а e == 4 262 263 264# Словари содержат ассоциативные массивы 265empty_dict = {} 266# Вот так описывается предзаполненный словарь 267filled_dict = {"one": 1, "two": 2, "three": 3} 268 269# Обратите внимание, что ключи для словарей должны быть неизменяемыми типами. Это 270# сделано для того, чтобы ключ мог быть преобразован в хеш для быстрого поиска. 271# Неизменяемые типы включают целые числа, числа с плавающей запятой, строки, 272# кортежи. 273invalid_dict = {[1,2,3]: "123"} # => Выбрасывает ошибку TypeError: unhashable type: 'list' 274valid_dict = {(1,2,3):[1,2,3]} # Однако значения могут быть любого типа. 275 276# Поиск значений с помощью [] 277filled_dict["one"] # => 1 278 279# Все ключи в виде списка получаются с помощью метода keys(). Его вызов нужно 280# обернуть в list(), так как обратно мы получаем итерируемый объект, о которых 281# поговорим позднее. Примечание - для Python версии <3.7, порядок словарных 282# ключей не гарантируется. Ваши результаты могут не точно соответствовать 283# приведенному ниже примеру. Однако, начиная с Python 3.7 элементы в словаре 284# сохраняют порядок, в котором они вставляются в словарь. 285list(filled_dict.keys()) # => ["three", "two", "one"] в Python <3.7 286list(filled_dict.keys()) # => ["one", "two", "three"] в Python 3.7+ 287 288 289# Все значения в виде списка можно получить с помощью values(). 290# И снова нам нужно обернуть вызов в list(), чтобы превратить 291# итерируемый объект в список. 292# То же самое замечание насчёт порядка ключей справедливо и здесь 293list(filled_dict.values()) # => [3, 2, 1] в Python <3.7 294list(filled_dict.values()) # => [1, 2, 3] в Python 3.7+ 295 296# При помощи ключевого слова in можно проверять наличие ключей в словаре 297"one" in filled_dict # => True 2981 in filled_dict # => False 299 300# Попытка получить значение по несуществующему ключу выбросит ошибку KeyError 301filled_dict["four"] # Выбрасывает ошибку KeyError 302 303# Чтобы избежать этого, используйте метод get() 304filled_dict.get("one") # => 1 305filled_dict.get("four") # => None 306# Метод get поддерживает аргумент по умолчанию, когда значение отсутствует 307filled_dict.get("one", 4) # => 1 308filled_dict.get("four", 4) # => 4 309 310# Метод setdefault() вставляет пару ключ-значение, только если такого ключа нет 311filled_dict.setdefault("five", 5) # filled_dict["five"] возвращает 5 312filled_dict.setdefault("five", 6) # filled_dict["five"] по-прежнему возвращает 5 313 314# Добавление элементов в словарь 315filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4} 316filled_dict["four"] = 4 # Другой способ добавления элементов 317 318# Удаляйте ключи из словаря с помощью ключевого слова del 319del filled_dict["one"] # Удаляет ключ "one" из словаря 320 321# В Python 3.5+ вы также можете использовать дополнительные параметры распаковки 322{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2} 323{'a': 1, **{'a': 2}} # => {'a': 2} 324 325 326# Множества содержат... ну, в общем, множества 327empty_set = set() 328# Инициализация множества набором значений. 329# Да, оно выглядит примерно как словарь. Ну извините, так уж вышло. 330filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} 331 332# Как и ключи словаря, элементы множества должны быть неизменяемыми. 333invalid_set = {[1], 1} # => Выбрасывает ошибку TypeError: unhashable type: 'list' 334valid_set = {(1,), 1} 335 336# Множеству можно назначать новую переменную 337filled_set = some_set 338filled_set.add(5) # {1, 2, 3, 4, 5} 339# В множествах нет повторяющихся элементов 340filled_set.add(5) # {1, 2, 3, 4, 5} 341 342# Пересечение множеств: & 343other_set = {3, 4, 5, 6} 344filled_set & other_set # => {3, 4, 5} 345 346# Объединение множеств: | 347filled_set | other_set # => {1, 2, 3, 4, 5, 6} 348 349# Разность множеств: - 350{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} 351 352# Симметричная разница: ^ 353{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} 354 355# Проверить, является ли множество слева надмножеством множества справа 356{1, 2} >= {1, 2, 3} # => False 357 358# Проверить, является ли множество слева подмножеством множества справа 359{1, 2} <= {1, 2, 3} # => True 360 361# Проверка на наличие в множестве: in 3622 in filled_set # => True 36310 in filled_set # => False 364 365# Сделать однослойную глубокую копию 366filled_set = some_set.copy() # {1, 2, 3, 4, 5} 367filled_set is some_set # => False 368 369 370#################################################### 371## 3. Поток управления и итерируемые объекты 372#################################################### 373 374# Для начала создадим переменную 375some_var = 5 376 377# Так выглядит выражение if. Отступы в python очень важны! 378# Конвенция заключается в использовании четырех пробелов, а не табуляции. 379# Pезультат: "some_var меньше, чем 10" 380if some_var > 10: 381 print("some_var точно больше, чем 10.") 382elif some_var < 10: # Выражение elif необязательно. 383 print("some_var меньше, чем 10.") 384else: # Это тоже необязательно. 385 print("some_var равно 10.") 386 387 388""" 389Циклы For проходят по спискам. 390Выводит: 391 собака — это млекопитающее 392 кошка — это млекопитающее 393 мышь — это млекопитающее 394""" 395for animal in ["собака", "кошка", "мышь"]: 396 # Можете использовать format() для интерполяции форматированных строк 397 print("{} — это млекопитающее".format(animal)) 398 399""" 400"range(число)" возвращает список чисел от нуля до заданного числа. 401Выводит: 402 0 403 1 404 2 405 3 406""" 407for i in range(4): 408 print(i) 409 410""" 411"range(начало, конец)" возвращает список чисел от начального числа 412к конечному, не включая конечное. 413Выводит: 414 4 415 5 416 6 417 7 418""" 419for i in range(4, 8): 420 print(i) 421 422""" 423"range(начало, конец, шаг)" возвращает список чисел от начального 424числа к конечному, увеличивая шаг за шагом. 425Если шаг не указан, значение по умолчанию - 1. 426Выводит: 427 4 428 6 429""" 430for i in range(4, 8, 2): 431 print(i) 432 433""" 434Можно перебрать список и получить индекс и значение каждого элемента в списке 435Выводит: 436 0 собака 437 1 кошка 438 2 мышь 439""" 440animals = ["собака", "кошка", "мышь"] 441for i, value in enumerate(animals): 442 print(i, value) 443 444""" 445Циклы while продолжаются до тех пор, пока указанное условие не станет ложным. 446Выводит: 447 0 448 1 449 2 450 3 451""" 452x = 0 453while x < 4: 454 print(x) 455 x += 1 # Краткая запись для x = x + 1 456 457 458# Обрабатывайте исключения блоками try/except 459try: 460 # Чтобы выбросить ошибку, используется raise 461 raise IndexError("Это ошибка индекса") 462except IndexError as e: 463 pass # pass — это просто отсутствие оператора. Обычно здесь происходит восстановление после ошибки. 464except (TypeError, NameError): 465 pass # Можно обработать больше одного исключения. 466else: # Необязательно. Добавляется за последним except. 467 print("Всё хорошо!") # Выполнится, только если не было никаких исключений. 468finally: # Необязательно. Выполнить при любых обстоятельствах. 469 print("Мы можем очистить ресурсы здесь") 470 471# Вместо try/finally чтобы очистить ресурсы, можно использовать оператор with 472with open("myfile.txt") as f: 473 for line in f: 474 print(line) 475 476# Запись в файл 477contents = {"aa": 12, "bb": 21} 478with open("myfile1.txt", "w+") as file: 479 file.write(str(contents)) # Записывает строку в файл 480 481with open("myfile2.txt", "w+") as file: 482 file.write(json.dumps(contents)) # Записывает объект в файл 483 484# Чтение из файла 485with open("myfile1.txt", "r+") as file: 486 contents = file.read() # Читает строку из файла 487print(contents) # => '{"aa": 12, "bb": 21}' 488 489with open("myfile2.txt", "r") as file: 490 contents = json.load(file) # Читает объект json из файла 491print(contents) # => {"aa": 12, "bb": 21} 492 493 494# Python предоставляет фундаментальную абстракцию, 495# которая называется итерируемым объектом (Iterable). 496# Итерируемый объект — это объект, который воспринимается как последовательность. 497# Объект, который возвратила функция range() — итерируемый. 498 499filled_dict = {"one": 1, "two": 2, "three": 3} 500our_iterable = filled_dict.keys() 501print(our_iterable) # => dict_keys(['one', 'two', 'three']). Это объект, реализующий интерфейс Iterable 502 503# Мы можем проходить по нему циклом. 504for i in our_iterable: 505 print(i) # Выводит one, two, three 506 507# Но мы не можем обращаться к элементу по индексу. 508our_iterable[1] # Выбрасывает ошибку TypeError 509 510# Итерируемый объект знает, как создавать итератор. 511our_iterator = iter(our_iterable) 512 513# Итератор может запоминать состояние при проходе по объекту. 514# Мы получаем следующий объект, вызывая функцию next(). 515next(our_iterator) # => "one" 516 517# Он сохраняет состояние при вызове next(). 518next(our_iterator) # => "two" 519next(our_iterator) # => "three" 520 521# Возвратив все данные, итератор выбрасывает исключение StopIteration 522next(our_iterator) # Выбрасывает исключение StopIteration 523 524# Мы можем проходить по нему циклом. 525our_iterator = iter(our_iterable) 526for i in our_iterator: 527 print(i) # Выводит one, two, three 528 529# Вы можете получить сразу все элементы итератора, вызвав на нём функцию list(). 530list(our_iterable) # => Возвращает ["one", "two", "three"] 531list(our_iterator) # => Возвращает [] потому что состояние сохраняется 532 533 534#################################################### 535## 4. Функции 536#################################################### 537 538# Используйте def для создания новых функций 539def add(x, y): 540 print("x равен %s, а y равен %s" % (x, y)) 541 return x + y # Возвращайте результат с помощью ключевого слова return 542 543# Вызов функции с аргументами 544add(5, 6) # => Выводит "x равен 5, а y равен 6" и возвращает 11 545 546# Другой способ вызова функции — вызов с именованными аргументами 547add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке. 548 549# Вы можете определить функцию, принимающую переменное число аргументов 550def varargs(*args): 551 return args 552 553varargs(1, 2, 3) # => (1,2,3) 554 555 556# А также можете определить функцию, принимающую переменное число 557# именованных аргументов 558def keyword_args(**kwargs): 559 return kwargs 560 561# Вызовем эту функцию и посмотрим, что из этого получится 562keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} 563 564# Если хотите, можете использовать оба способа одновременно 565def all_the_args(*args, **kwargs): 566 print(args) 567 print(kwargs) 568""" 569all_the_args(1, 2, a=3, b=4) выводит: 570 (1, 2) 571 {"a": 3, "b": 4} 572""" 573 574# Вызывая функции, можете сделать наоборот! 575# Используйте символ * для распаковки кортежей и ** для распаковки словарей 576args = (1, 2, 3, 4) 577kwargs = {"a": 3, "b": 4} 578all_the_args(*args) # эквивалентно all_the_args(1, 2, 3, 4) 579all_the_args(**kwargs) # эквивалентно all_the_args(a=3, b=4) 580all_the_args(*args, **kwargs) # эквивалентно all_the_args(1, 2, 3, 4, a=3, b=4) 581 582# Возврат нескольких значений (с назначением кортежей) 583def swap(x, y): 584 return y, x # Возвращает несколько значений в виде кортежа без скобок. 585 # (Примечание: скобки исключены, но могут быть включены) 586 587x = 1 588y = 2 589x, y = swap(x, y) # => x = 2, y = 1 590# (x, y) = swap(x,y) # Снова, скобки были исключены, но могут быть включены. 591 592# Область определения функций 593x = 5 594 595def set_x(num): 596 # Локальная переменная x — это не то же самое, что глобальная переменная x 597 x = num # => 43 598 print(x) # => 43 599 600def set_global_x(num): 601 global x 602 print(x) # => 5 603 x = num # Глобальная переменная x теперь равна 6 604 print(x) # => 6 605 606set_x(43) 607set_global_x(6) 608 609# Python имеет функции первого класса 610def create_adder(x): 611 def adder(y): 612 return x + y 613 return adder 614 615add_10 = create_adder(10) 616add_10(3) # => 13 617 618# Также есть и анонимные функции 619(lambda x: x > 2)(3) # => True 620(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 621 622# Есть встроенные функции высшего порядка 623list(map(add_10, [1, 2, 3])) # => [11, 12, 13] 624list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3] 625 626list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7] 627 628# Для удобного отображения и фильтрации можно использовать списочные интерпретации 629# Интерпретация списка сохраняет вывод в виде списка, который сам может быть вложенным списком 630[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] 631[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] 632 633# Вы также можете создавать интерпретации множеств и словарей. 634{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'} 635{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} 636 637 638#################################################### 639## 5. Модули 640#################################################### 641 642# Вы можете импортировать модули 643import math 644print(math.sqrt(16)) # => 4.0 645 646# Вы можете получить определенные функции из модуля 647from math import ceil, floor 648print(ceil(3.7)) # => 4.0 649print(floor(3.7)) # => 3.0 650 651# Вы можете импортировать все функции из модуля. 652# Предупреждение: это не рекомендуется 653from math import * 654 655# Вы можете сократить имена модулей 656import math as m 657math.sqrt(16) == m.sqrt(16) # => True 658 659# Модули Python - это обычные файлы Python. Вы 660# можете писать свои собственные и импортировать их. Имя 661# модуля совпадает с именем файла. 662 663# Вы можете узнать, какие функции и атрибуты 664# определены в модуле. 665import math 666dir(math) 667 668# Если у вас есть скрипт Python с именем math.py в той же папке, 669# что и ваш текущий скрипт, файл math.py будет 670# будет загружен вместо встроенного модуля Python. 671# Это происходит потому, что локальная папка имеет приоритет 672# над встроенными библиотеками Python. 673 674 675#################################################### 676## 6. Классы 677#################################################### 678 679# Мы используем оператор class для создания класса 680class Human: 681 682 # Атрибут класса. Он используется всеми экземплярами этого класса 683 species = "Гомосапиенс" 684 685 # Обычный конструктор, вызывается при инициализации экземпляра класса 686 # Обратите внимание, что двойное подчёркивание в начале и в конце имени 687 # означает объекты и атрибуты, которые используются Python, но находятся 688 # в пространствах имён, управляемых пользователем. 689 # Методы (или объекты или атрибуты), например: 690 # __init__, __str__, __repr__ и т. д. называются специальными методами. 691 # Не придумывайте им имена самостоятельно. 692 def __init__(self, name): 693 # Присваивание значения аргумента атрибуту 694 self.name = name 695 696 # Инициализация свойства 697 self._age = 0 698 699 # Метод экземпляра. Все методы принимают self в качестве первого аргумента 700 def say(self, msg): 701 return "{name}: {message}".format(name=self.name, message=msg) 702 703 # Другой метод экземпляра 704 def sing(self): 705 return 'йо... йо... проверка микрофона... раз, два... раз, два...' 706 707 # Метод класса разделяется между всеми экземплярами 708 # Они вызываются с указыванием вызывающего класса в качестве первого аргумента 709 @classmethod 710 def get_species(cls): 711 return cls.species 712 713 # Статический метод вызывается без ссылки на класс или экземпляр 714 @staticmethod 715 def grunt(): 716 return "*grunt*" 717 718 # property похоже на геттер. 719 # Оно превращает метод age() в одноименный атрибут только для чтения. 720 # Однако нет необходимости писать тривиальные геттеры и сеттеры в Python. 721 @property 722 def age(self): 723 return self._age 724 725 # Это позволяет установить свойство 726 @age.setter 727 def age(self, age): 728 self._age = age 729 730 # Это позволяет удалить свойство 731 @age.deleter 732 def age(self): 733 del self._age 734 735 736# Когда интерпретатор Python читает исходный файл, он выполняет весь его код. 737# Проверка __name__ гарантирует, что этот блок кода выполняется только тогда, когда 738# этот модуль - это основная программа. 739if __name__ == '__main__': 740 # Инициализация экземпляра класса 741 i = Human(name="Иван") 742 i.say("привет") # Выводит: "Иван: привет" 743 j = Human("Пётр") 744 j.say("привет") # Выводит: "Пётр: привет" 745 # i и j являются экземплярами типа Human, или другими словами: они являются объектами Human 746 747 # Вызов метода класса 748 i.say(i.get_species()) # "Иван: Гомосапиенс" 749 # Изменение разделяемого атрибута 750 Human.species = "Неандертальец" 751 i.say(i.get_species()) # => "Иван: Неандертальец" 752 j.say(j.get_species()) # => "Пётр: Неандертальец" 753 754 # Вызов статического метода 755 print(Human.grunt()) # => "*grunt*" 756 757 # Невозможно вызвать статический метод с экземпляром объекта 758 # потому что i.grunt() автоматически поместит "self" (объект i) в качестве аргумента 759 print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given 760 761 # Обновить свойство для этого экземпляра 762 i.age = 42 763 # Получить свойство 764 i.say(i.age) # => "Иван: 42" 765 j.say(j.age) # => "Пётр: 0" 766 # Удалить свойство 767 del i.age 768 # i.age # => это выбрасило бы ошибку AttributeError 769 770 771#################################################### 772## 6.1 Наследование 773#################################################### 774 775# Наследование позволяет определять новые дочерние классы, которые наследуют методы и 776# переменные от своего родительского класса. 777 778# Используя класс Human, определенный выше как базовый или родительский класс, мы можем 779# определить дочерний класс Superhero, который наследует переменные класса, такие как 780# "species", "name" и "age", а также методы, такие как "sing" и "grunt" из класса Human, 781# но также может иметь свои уникальные свойства. 782 783# Чтобы воспользоваться преимуществами модульности по файлам, вы можете поместить 784# вышеперечисленные классы в их собственные файлы, например, human.py 785 786# Чтобы импортировать функции из других файлов, используйте следующий формат 787# from "имя-файла-без-расширения" import "функция-или-класс" 788 789from human import Human 790 791 792# Укажите родительский класс(ы) как параметры определения класса 793class Superhero(Human): 794 795 # Если дочерний класс должен наследовать все определения родителя без каких-либо 796 # изменений, вы можете просто использовать ключевое слово pass (и ничего больше), 797 # но в этом случае оно закомментировано, чтобы разрешить уникальный дочерний класс: 798 # pass 799 800 # Дочерние классы могут переопределять атрибуты своих родителей 801 species = 'Сверхчеловек' 802 803 # Дочерние классы автоматически наследуют конструктор родительского класса, включая 804 # его аргументы, но также могут определять дополнительные аргументы или определения 805 # и переопределять его методы, такие как конструктор класса. 806 # Этот конструктор наследует аргумент "name" от класса "Human" 807 # и добавляет аргументы "superpower" и "movie": 808 def __init__(self, name, movie=False, 809 superpowers=["сверхсила", "пуленепробиваемость"]): 810 811 # добавить дополнительные атрибуты класса: 812 self.fictional = True 813 self.movie = movie 814 # помните об изменяемых значениях по умолчанию, 815 # поскольку значения по умолчанию являются общими 816 self.superpowers = superpowers 817 818 # Функция "super" позволяет вам получить доступ к методам родительского класса, 819 # которые переопределяются дочерним, в данном случае, методом __init__. 820 # Это вызывает конструктор родительского класса: 821 super().__init__(name) 822 823 # переопределить метод sing 824 def sing(self): 825 return 'Бам, бам, БАМ!' 826 827 # добавить дополнительный метод экземпляра 828 def boast(self): 829 for power in self.superpowers: 830 print("Я обладаю силой '{pow}'!".format(pow=power)) 831 832 833if __name__ == '__main__': 834 sup = Superhero(name="Тик") 835 836 # Проверка типа экземпляра 837 if isinstance(sup, Human): 838 print('Я человек') 839 if type(sup) is Superhero: 840 print('Я супергерой') 841 842 # Получить порядок поиска разрешения метода (MRO), 843 # используемый как getattr(), так и super() 844 # Этот атрибут является динамическим и может быть обновлен 845 print(Superhero.__mro__) # => (<class '__main__.Superhero'>, 846 # => <class 'human.Human'>, <class 'object'>) 847 848 # Вызывает родительский метод, но использует свой собственный атрибут класса 849 print(sup.get_species()) # => Сверхчеловек 850 851 # Вызов переопределенного метода 852 print(sup.sing()) # => Бам, бам, БАМ! 853 854 # Вызывает метод из Human 855 sup.say('Ложка') # => Тик: Ложка 856 857 # Метод вызова, существующий только в Superhero 858 sup.boast() # => Я обладаю силой 'сверхсила'! 859 # => Я обладаю силой 'пуленепробиваемость'! 860 861 # Атрибут унаследованного класса 862 sup.age = 31 863 print(sup.age) # => 31 864 865 # Атрибут, который существует только в Superhero 866 print('Достоин ли я Оскара? ' + str(sup.movie)) 867 868 869#################################################### 870## 6.2 Множественное наследование 871#################################################### 872 873# Eще одно определение класса 874# bat.py 875class Bat: 876 877 species = 'Летучая мышь' 878 879 def __init__(self, can_fly=True): 880 self.fly = can_fly 881 882 # В этом классе также есть метод say 883 def say(self, msg): 884 msg = '... ... ...' 885 return msg 886 887 # И свой метод тоже 888 def sonar(self): 889 return '))) ... (((' 890 891if __name__ == '__main__': 892 b = Bat() 893 print(b.say('привет')) 894 print(b.fly) 895 896 897# И еще одно определение класса, унаследованное от Superhero и Bat 898# superhero.py 899from superhero import Superhero 900from bat import Bat 901 902# Определите Batman как дочерний класс, унаследованный от Superhero и Bat 903class Batman(Superhero, Bat): 904 905 def __init__(self, *args, **kwargs): 906 # Обычно для наследования атрибутов необходимо вызывать super: 907 # super(Batman, self).__init__(*args, **kwargs) 908 # Однако здесь мы имеем дело с множественным наследованием, а super() 909 # работает только со следующим базовым классом в списке MRO. 910 # Поэтому вместо этого мы вызываем __init__ для всех родителей. 911 # Использование *args и **kwargs обеспечивает чистый способ передачи 912 # аргументов, когда каждый родитель "очищает слой луковицы". 913 Superhero.__init__(self, 'анонимный', movie=True, 914 superpowers=['Богатый'], *args, **kwargs) 915 Bat.__init__(self, *args, can_fly=False, **kwargs) 916 # переопределить значение атрибута name 917 self.name = 'Грустный Бен Аффлек' 918 919 def sing(self): 920 return 'на на на на на бэтмен!' 921 922 923if __name__ == '__main__': 924 sup = Batman() 925 926 # Получить порядок поиска разрешения метода (MRO), 927 # используемый как getattr(), так и super() 928 # Этот атрибут является динамическим и может быть обновлен 929 print(Batman.__mro__) # => (<class '__main__.Batman'>, 930 # => <class 'superhero.Superhero'>, 931 # => <class 'human.Human'>, 932 # => <class 'bat.Bat'>, <class 'object'>) 933 934 # Вызывает родительский метод, но использует свой собственный атрибут класса 935 print(sup.get_species()) # => Сверхчеловек 936 937 # Вызов переопределенного метода 938 print(sup.sing()) # => на на на на на бэтмен! 939 940 # Вызывает метод из Human, потому что порядок наследования имеет значение 941 sup.say('Я согласен') # => Грустный Бен Аффлек: Я согласен 942 943 # Вызов метода, существующий только во втором родителе 944 print(sup.sonar()) # => ))) ... ((( 945 946 # Атрибут унаследованного класса 947 sup.age = 100 948 print(sup.age) # => 100 949 950 # Унаследованный атрибут от второго родителя, 951 # значение по умолчанию которого было переопределено. 952 print('Могу ли я летать? ' + str(sup.fly)) # => Могу ли я летать? False 953 954 955#################################################### 956## 7. Дополнительно 957#################################################### 958 959# Генераторы помогут выполнить ленивые вычисления 960def double_numbers(iterable): 961 for i in iterable: 962 yield i + i 963 964# Генераторы эффективны с точки зрения памяти, потому что они загружают только данные, 965# необходимые для обработки следующего значения в итерации. 966# Это позволяет им выполнять операции с недопустимо большими диапазонами значений. 967# ПРИМЕЧАНИЕ: "range" заменяет "xrange" в Python 3. 968for i in double_numbers(range(1, 900000000)): # "range" - генератор. 969 print(i) 970 if i >= 30: 971 break 972 973# Так же, как вы можете создать интерпретации списков, вы можете создать и 974# интерпретации генераторов. 975values = (-x for x in [1,2,3,4,5]) 976for x in values: 977 print(x) # Выводит -1 -2 -3 -4 -5 978 979# Вы также можете преобразовать интерпретацию генератора непосредственно в список. 980values = (-x for x in [1,2,3,4,5]) 981gen_to_list = list(values) 982print(gen_to_list) # => [-1, -2, -3, -4, -5] 983 984 985# Декораторы 986# В этом примере "beg" оборачивает "say". 987# Если say_please равно True, он изменит возвращаемое сообщение. 988from functools import wraps 989 990 991def beg(target_function): 992 @wraps(target_function) 993 def wrapper(*args, **kwargs): 994 msg, say_please = target_function(*args, **kwargs) 995 if say_please: 996 return "{} {}".format(msg, "Пожалуйста! У меня нет денег :(") 997 return msg 998 999 return wrapper 1000 1001 1002@beg 1003def say(say_please=False): 1004 msg = "Вы не купите мне пива?" 1005 return msg, say_please 1006 1007 1008print(say()) # Вы не купите мне пива? 1009print(say(say_please=True)) # Вы не купите мне пива? Пожалуйста! У меня нет денег :(

Хотите ещё?

Бесплатные онлайн-материалы