2014-09-09 19:49:29 +04:00
---
2020-02-12 07:15:29 +03:00
language: Python
2014-09-09 19:49:29 +04:00
lang: ru-ru
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
- ["Steven Basart", "http://github.com/xksteven"]
translators:
- ["Andre Polykanine", "https://github.com/Oire"]
2020-09-02 02:33:37 +03:00
- ["Anton Grouchtchak", "https://github.com/Teraskull"]
2020-02-12 08:23:31 +03:00
filename: learnpython-ru.py
2014-09-09 19:49:29 +04:00
---
Язык Python был создан Гвидо ван Россумом в начале 90-х . Сейчас это один из
2015-01-18 01:00:06 +03:00
самых популярных языков. Я влюбился в Python за понятный и доходчивый синтаксис — это
2014-09-09 19:49:29 +04:00
почти что исполняемый псевдокод.
С благодарностью жду ваших отзывов: [@louiedinh ](http://twitter.com/louiedinh )
или louiedinh [at] [почтовый сервис Google]
Замечание: Эта статья относится только к Python 3.
Если вы хотите изучить Python 2.7, обратитесь к другой статье.
```python
2020-09-02 02:33:37 +03:00
2014-09-09 19:49:29 +04:00
# Однострочные комментарии начинаются с символа решётки.
2020-09-02 02:33:37 +03:00
""" Многострочный текст может быть
2014-09-09 19:49:29 +04:00
записан, используя 3 знака " и обычно используется
2014-09-19 18:03:33 +04:00
в качестве встроенной документации
2014-09-09 19:49:29 +04:00
"""
####################################################
## 1. Примитивные типы данных и операторы
####################################################
# У вас есть числа
2020-09-02 02:33:37 +03:00
3 # => 3
2014-09-09 19:49:29 +04:00
# Математика работает вполне ожидаемо
2020-09-02 02:33:37 +03:00
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
2014-09-09 19:49:29 +04:00
35 / 5 # => 7.0
# Результат целочисленного деления округляется в меньшую сторону
# как для положительных, так и для отрицательных чисел.
2020-09-02 02:33:37 +03:00
5 // 3 # => 1
-5 // 3 # => -2
5.0 // 3.0 # => 1.0 # работает и для чисел с плавающей запятой
2014-09-09 19:49:29 +04:00
-5.0 // 3.0 # => -2.0
2020-09-02 02:33:37 +03:00
# # Результат деления возвращает число с плавающей запятой
10.0 / 3 # => 3.3333333333333335
2014-09-09 19:49:29 +04:00
# Остаток от деления
2020-09-02 02:33:37 +03:00
7 % 3 # => 1
2014-09-09 19:49:29 +04:00
# Возведение в степень
2020-09-02 02:33:37 +03:00
2**3 # => 8
2014-09-09 19:49:29 +04:00
# Приоритет операций указывается скобками
2020-09-02 02:33:37 +03:00
1 + 3 * 2 # => 7
(1 + 3) * 2 # => 8
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Булевы значения - примитивы (Обратите внимание на заглавную букву)
True # => True
False # => False
2014-09-09 19:49:29 +04:00
# Для отрицания используется ключевое слово not
2020-09-02 02:33:37 +03:00
not True # => False
not False # => True
# Булевы операторы
# Обратите внимание: ключевые слова "and" и "or" чувствительны к регистру букв
True and False # => False
False or True # => True
# True и False на самом деле 1 и 0, но с разными ключевыми словами
True + True # => 2
True * 8 # => 8
False - 5 # => -5
# Операторы сравнения обращают внимание на числовое значение True и False
0 == False # => True
1 == True # => True
2 == True # => False
-5 != False # => True
# Использование булевых логических операторов на типах int превращает их в булевы значения, но возвращаются оригинальные значения
# Н е путайте с bool(ints) и bitwise and/or (&,|)
bool(0) # => False
bool(4) # => True
bool(-6) # => True
0 and 2 # => 0
-5 or 0 # => -5
2015-01-18 01:00:06 +03:00
2014-09-09 19:49:29 +04:00
# Равенство — это ==
2020-09-02 02:33:37 +03:00
1 == 1 # => True
2 == 1 # => False
2014-09-09 19:49:29 +04:00
# Неравенство — это !=
2020-09-02 02:33:37 +03:00
1 != 1 # => False
2 != 1 # => True
2014-09-09 19:49:29 +04:00
# Ещё немного сравнений
2020-09-02 02:33:37 +03:00
1 < 10 # = > True
1 > 10 # => False
2 < = 2 # => True
2 >= 2 # => True
# Проверка, находится ли значение в диапазоне
1 < 2 and 2 < 3 # = > True
2 < 3 and 3 < 2 # = > False
# Сравнения могут быть записаны цепочкой
1 < 2 < 3 # = > True
2 < 3 < 2 # = > False
# (is vs. ==) ключевое слово is проверяет, относятся ли две переменные к одному и тому же объекту, но == проверяет если указанные объекты имеют одинаковые значения.
a = [1, 2, 3, 4] # a указывает на новый список, [1, 2, 3, 4]
b = a # b указывает на то, что указывает a
b is a # => True, a и b относятся к одному и тому же объекту
b == a # => True, Объекты a и b равны
b = [1, 2, 3, 4] # b указывает на новый список, [1, 2, 3, 4]
b is a # => False, a и b не относятся к одному и тому же объекту
b == a # => True, Объекты a и b равны
2014-09-09 19:49:29 +04:00
# Строки определяются символом " или '
"Это строка."
'Это тоже строка.'
2015-01-18 01:00:06 +03:00
# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим.
2020-09-02 02:33:37 +03:00
"Привет " + "мир!" # => "Привет мир!"
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Строки (но не переменные) могут быть объединены без использования '+'
"Привет " "мир!" # => "Привет мир!"
2017-12-04 10:13:46 +03:00
2014-09-09 19:49:29 +04:00
# С о строкой можно работать, как с о списком символов
2020-09-02 02:33:37 +03:00
"Привет мир!"[0] # => 'П'
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Вы можете найти длину строки
len("Это строка") # => 10
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Вы также можете форматировать, используя f-строки (в Python 3.6+)
name = "Рейко"
f"Она сказала, что е е зовут {name}." # => "Она сказала, что е е зовут Рейко"
# Вы можете поместить любой оператор Python в фигурные скобки, и он будет выведен в строке.
f"{name} состоит из {len(name)} символов." # => "Рэйко состоит из 5 символов."
2014-09-09 19:49:29 +04:00
# None является объектом
2020-09-02 02:33:37 +03:00
None # => None
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Н е используйте оператор равенства "==" для сравнения
# объектов с None. Используйте для этого "is"
"etc" is None # => False
None is None # => True
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# None, 0 и пустые строки/списки/словари/кортежи приводятся к False.
2014-09-09 19:49:29 +04:00
# В с е остальные значения равны True
2020-09-02 02:33:37 +03:00
bool(0) # => False
2014-09-09 19:49:29 +04:00
bool("") # => False
2020-09-02 02:33:37 +03:00
bool([]) # => False
bool({}) # => False
bool(()) # => False
2014-09-09 19:49:29 +04:00
####################################################
2020-09-02 02:33:37 +03:00
## 2. Переменные и Коллекции
2014-09-09 19:49:29 +04:00
####################################################
2015-01-18 01:00:06 +03:00
# В Python есть функция Print
2020-09-02 02:33:37 +03:00
print("Я Python. Приятно познакомиться!") # => Я Python. Приятно познакомиться!
# По умолчанию функция, print() также выводит новую строку в конце.
# Используйте необязательный аргумент end, чтобы изменить последнюю строку.
print("Привет мир", end="!") # => Привет мир!
# Простой способ получить входные данные из консоли
input_string_var = input("Введите данные: ") # Возвращает данные в виде строки
# Примечание: в более ранних версиях Python метод input() назывался raw_input()
2014-09-09 19:49:29 +04:00
2015-01-18 01:00:06 +03:00
# Объявлять переменные перед инициализацией не нужно.
2014-09-09 19:49:29 +04:00
# По соглашению используется нижний_р е г ис тр _с _по дчёр кива ниями
some_var = 5
2020-09-02 02:33:37 +03:00
some_var # => 5
# При попытке доступа к неинициализированной переменной выбрасывается исключение.
# О б исключениях см. раздел "Поток управления и итерируемые объекты".
some_unknown_var # Выбрасывает ошибку NameError
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# if можно использовать как выражение
# Эквивалент тернарного оператора '?:' в C
"да!" if 0 > 1 else "нет!" # => "нет!"
2014-09-09 19:49:29 +04:00
# Списки хранят последовательности
li = []
2015-01-18 01:00:06 +03:00
# Можно сразу начать с заполненного списка
2014-09-09 19:49:29 +04:00
other_li = [4, 5, 6]
2020-09-02 02:33:37 +03:00
# Объекты добавляются в конец списка методом append()
li.append(1) # [1]
li.append(2) # [1, 2]
li.append(4) # [1, 2, 4]
li.append(3) # [1, 2, 4, 3]
# И удаляются с конца методом pop()
li.pop() # => возвращает 3 и li становится равен [1, 2, 4]
2014-09-09 19:49:29 +04:00
# Положим элемент обратно
2020-09-02 02:33:37 +03:00
li.append(3) # [1, 2, 4, 3].
2014-09-09 19:49:29 +04:00
# Обращайтесь с о списком, как с обычным массивом
2020-09-02 02:33:37 +03:00
li[0] # => 1
2014-09-09 19:49:29 +04:00
# Обратимся к последнему элементу
2020-09-02 02:33:37 +03:00
li[-1] # => 3
2014-09-09 19:49:29 +04:00
# Попытка выйти за границы массива приведёт к ошибке индекса
2020-09-02 02:33:37 +03:00
li[4] # Выбрасывает ошибку IndexError
2014-09-09 19:49:29 +04:00
2015-01-18 01:00:06 +03:00
# Можно обращаться к диапазону, используя так называемые срезы
2014-09-09 19:49:29 +04:00
# (Для тех, кто любит математику, это называется замкнуто-открытый интервал).
2020-09-02 02:33:37 +03:00
li[1:3] # Вернуть список из индекса с 1 по 3 => [2, 4]
li[2:] # Вернуть список, начиная с индекса 2 => [4, 3]
li[:3] # Вернуть список с начала до индекса 3 => [1, 2, 4]
li[::2] # Вернуть список, выбирая каждую вторую запись => [1, 4]
li[::-1] # Вернуть список в обратном порядке => [3, 4, 2, 1]
2015-01-18 01:00:06 +03:00
# Используйте сочетания всего вышеназванного для выделения более сложных срезов
2014-09-09 19:49:29 +04:00
# li[начало:конец:шаг]
2020-09-02 02:33:37 +03:00
# Сделать однослойную глубокую копию, используя срезы
li2 = li[:] # => li2 = [1, 2, 4, 3], но (li2 is li) вернет False.
2014-09-09 19:49:29 +04:00
# Удаляем произвольные элементы из списка оператором del
2020-09-02 02:33:37 +03:00
del li[2] # [1, 2, 3]
# Удалить первое вхождение значения
li.remove(2) # [1, 3]
li.remove(2) # Выбрасывает ошибку ValueError поскольку 2 нет в списке
# Вставить элемент по определенному индексу
li.insert(1, 2) # [1, 2, 3]
# Получить индекс первого найденного элемента, соответствующего аргументу
li.index(2) # => 1
li.index(4) # Выбрасывает ошибку ValueError поскольку 4 нет в списке
2014-09-09 19:49:29 +04:00
2015-01-18 01:00:06 +03:00
# Вы можете складывать, или, как ещё говорят, конкатенировать списки
# Обратите внимание: значения li и other_li при этом не изменились.
2020-09-02 02:33:37 +03:00
li + other_li # => [1, 2, 3, 4, 5, 6]
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Объединять списки можно методом extend()
2014-09-09 19:49:29 +04:00
li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
2020-09-02 02:33:37 +03:00
# Проверить элемент на наличие в списке можно оператором in
1 in li # => True
2014-09-09 19:49:29 +04:00
# Длина списка вычисляется функцией len
2020-09-02 02:33:37 +03:00
len(li) # => 6
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Кортежи похожи на списки, только неизменяемые
2014-09-09 19:49:29 +04:00
tup = (1, 2, 3)
2020-09-02 02:33:37 +03:00
tup[0] # => 1
tup[0] = 3 # Выбрасывает ошибку TypeError
# Обратите внимание, что кортеж длины 1 должен иметь запятую после последнего элемента, но кортежи другой длины, даже 0, не должны.
type((1)) # => < class ' int ' >
type((1,)) # => < class ' tuple ' >
type(()) # => < class ' tuple ' >
2014-09-09 19:49:29 +04:00
# Всё то же самое можно делать и с кортежами
2020-09-02 02:33:37 +03:00
len(tup) # => 3
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
tup[:2] # => (1, 2)
2 in tup # => True
2014-09-09 19:49:29 +04:00
# Вы можете распаковывать кортежи (или списки) в переменные
2020-09-02 02:33:37 +03:00
a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
# Вы также можете сделать расширенную распаковку
a, *b, c = (1, 2, 3, 4) # a теперь 1, b теперь [2, 3] и c теперь 4
2014-09-09 19:49:29 +04:00
# Кортежи создаются по умолчанию, если опущены скобки
2020-09-02 02:33:37 +03:00
d, e, f = 4, 5, 6 # кортеж 4, 5, 6 распаковывается в переменные d, e и f
# соответственно, d = 4, e = 5 и f = 6
2014-09-09 19:49:29 +04:00
# Обратите внимание, как легко поменять местами значения двух переменных
2020-09-02 02:33:37 +03:00
e, d = d, e # теперь d == 5, а e == 4
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Словари содержат ассоциативные массивы
2014-09-09 19:49:29 +04:00
empty_dict = {}
# Вот так описывается предзаполненный словарь
filled_dict = {"one": 1, "two": 2, "three": 3}
2020-09-02 02:33:37 +03:00
# Обратите внимание, что ключи для словарей должны быть неизменяемыми типами. Это
# сделано для того, чтобы ключ может быть преобразован в хеш для быстрого поиска.
# Неизменяемые типы включают целые числа, числа с плавающей запятой, строки, кортежи.
invalid_dict = {[1,2,3]: "123"} # => Выбрасывает ошибку TypeError: unhashable type: 'list'
valid_dict = {(1,2,3):[1,2,3]} # Однако значения могут быть любого типа.
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Поиск значений с помощью []
filled_dict["one"] # => 1
# В с е ключи в виде списка получаются с помощью метода keys().
2014-09-09 19:49:29 +04:00
# Е г о вызов нужно обернуть в list(), так как обратно мы получаем
2020-09-02 02:33:37 +03:00
# итерируемый объект, о которых поговорим позднее. Примечание - для Python
# версии <3.7, порядок словарных ключей не гарантируется. Ваши результаты могут
# не точно соответствовать приведенному ниже примеру. Однако, начиная с Python 3.7
# элементы в словаре сохраняют порядок, в котором они вставляются в словарь.
list(filled_dict.keys()) # => ["three", "two", "one"] в Python < 3.7
list(filled_dict.keys()) # => ["one", "two", "three"] в Python 3.7+
2014-09-09 19:49:29 +04:00
# В с е значения в виде списка можно получить с помощью values().
# И снова нам нужно обернуть вызов в list(), чтобы превратить
# итерируемый объект в список.
# Т о же самое замечание насчёт порядка ключей справедливо и здесь
2020-09-02 02:33:37 +03:00
list(filled_dict.values()) # => [3, 2, 1] в Python < 3.7
list(filled_dict.values()) # => [1, 2, 3] в Python 3.7+
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# При помощи ключевого слова in можно проверять наличие ключей в словаре
"one" in filled_dict # => True
1 in filled_dict # => False
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Попытка получить значение по несуществующему ключу выбросит ошибку KeyError
filled_dict["four"] # Выбрасывает ошибку KeyError
2014-09-09 19:49:29 +04:00
2015-01-18 01:00:06 +03:00
# Чтобы избежать этого, используйте метод get()
2020-09-02 02:33:37 +03:00
filled_dict.get("one") # => 1
filled_dict.get("four") # => None
# Метод get поддерживает аргумент по умолчанию, когда значение отсутствует
filled_dict.get("one", 4) # => 1
filled_dict.get("four", 4) # => 4
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Метод setdefault() вставляет пару ключ-значение, только если такого ключа нет
filled_dict.setdefault("five", 5) # filled_dict["five"] возвращает 5
filled_dict.setdefault("five", 6) # filled_dict["five"] по-прежнему возвращает 5
2014-09-09 19:49:29 +04:00
2015-01-18 01:00:06 +03:00
# Добавление элементов в словарь
2020-09-02 02:33:37 +03:00
filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
filled_dict["four"] = 4 # Другой способ добавления элементов
# Удаляйте ключи из словаря с помощью ключевого слова del
del filled_dict["one"] # Удаляет ключ "one" из словаря
# После Python 3.5 вы также можете использовать дополнительные параметры распаковки
{'a': 1, ** {'b': 2}} # => {'a': 1, 'b': 2}
{'a': 1, ** {'a': 2}} # => {'a': 2}
2015-01-18 01:00:06 +03:00
2014-09-09 19:49:29 +04:00
# Множества содержат... ну, в общем, множества
empty_set = set()
# Инициализация множества набором значений.
2020-09-02 02:33:37 +03:00
# Да, оно выглядит примерно как словарь. Н у извините, так уж вышло.
filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
# Similar to keys of a dictionary, elements of a set have to be immutable.
# Как и ключи словаря, элементы множества должны быть неизменяемыми.
invalid_set = {[1], 1} # => Выбрасывает ошибку TypeError: unhashable type: 'list'
valid_set = {(1,), 1}
2014-09-09 19:49:29 +04:00
# Множеству можно назначать новую переменную
filled_set = some_set
2020-09-02 02:33:37 +03:00
filled_set.add(5) # {1, 2, 3, 4, 5}
# В множествах нет повторяющихся элементов
filled_set.add(5) # {1, 2, 3, 4, 5}
2014-09-09 19:49:29 +04:00
# Пересечение множеств: &
other_set = {3, 4, 5, 6}
2020-09-02 02:33:37 +03:00
filled_set & other_set # => {3, 4, 5}
2014-09-09 19:49:29 +04:00
# Объединение множеств: |
2020-09-02 02:33:37 +03:00
filled_set | other_set # => {1, 2, 3, 4, 5, 6}
2014-09-09 19:49:29 +04:00
# Разность множеств: -
2020-09-02 02:33:37 +03:00
{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
# Симметричная разница: ^
{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
# Проверить, является ли множество слева надмножеством множества справа
{1, 2} >= {1, 2, 3} # => False
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Проверить, является ли множество слева подмножеством множества справа
{1, 2} < = {1, 2, 3} # => True
# Проверка на наличие в множестве: in
2 in filled_set # => True
10 in filled_set # => False
# Сделать однослойную глубокую копию
filled_set = some_set.copy() # {1, 2, 3, 4, 5}
filled_set is some_set # => False
2014-09-09 19:49:29 +04:00
####################################################
## 3. Поток управления и итерируемые объекты
####################################################
2020-09-02 02:33:37 +03:00
# Для начала создадим переменную
2014-09-09 19:49:29 +04:00
some_var = 5
# Так выглядит выражение if. Отступы в python очень важны!
2020-09-02 02:33:37 +03:00
# Конвенция заключается в использовании четырех пробелов, а не табуляции.
# Pе зу льта т: "some_var меньше, чем 10"
2014-09-09 19:49:29 +04:00
if some_var > 10:
2020-09-02 02:33:37 +03:00
print("some_var точно больше, чем 10.")
elif some_var < 10: # Выражение elif необязательно .
2014-09-09 19:49:29 +04:00
print("some_var меньше, чем 10.")
2020-09-02 02:33:37 +03:00
else: # Это тоже необязательно.
2014-09-09 19:49:29 +04:00
print("some_var равно 10.")
2020-09-02 02:33:37 +03:00
"""
Циклы For проходят по спискам.
Выводит:
собака — это млекопитающее
кошка — это млекопитающее
мышь — это млекопитающее
"""
2014-09-09 19:49:29 +04:00
for animal in ["собака", "кошка", "мышь"]:
# Можете использовать format() для интерполяции форматированных строк
print("{} — это млекопитающее".format(animal))
2020-09-02 02:33:37 +03:00
2014-09-09 19:49:29 +04:00
"""
2020-09-02 02:33:37 +03:00
"range(число)" возвращает список чисел
2014-09-09 19:49:29 +04:00
от нуля до заданного числа
2020-09-02 02:33:37 +03:00
Выводит:
2014-09-09 19:49:29 +04:00
0
1
2
3
"""
for i in range(4):
print(i)
2020-09-02 02:33:37 +03:00
"""
"range(нижнее, верхнее)" возвращает список чисел
от нижнего числа к верхнему
Выводит:
4
5
6
7
"""
for i in range(4, 8):
print(i)
"""
"range(нижнее, верхнее, шаг)" возвращает список чисел
от нижнего числа к верхнему, от нижнего числа к верхнему, увеличивая
шаг за шагом. Если шаг не указан, значение по умолчанию - 1.
Выводит:
4
6
"""
for i in range(4, 8, 2):
print(i)
"""
Чтобы перебрать список и получить индекс и значение каждого элемента в списке
Выводит:
0 собака
1 кошка
2 мышь
"""
animals = ["собака", "кошка", "мышь"]
for i, value in enumerate(animals):
print(i, value)
2014-09-09 19:49:29 +04:00
"""
Циклы while продолжаются до тех пор, пока указанное условие не станет ложным.
2020-09-02 02:33:37 +03:00
Выводит:
2014-09-09 19:49:29 +04:00
0
1
2
3
"""
x = 0
while x < 4:
print(x)
x += 1 # Краткая запись для x = x + 1
# Обрабатывайте исключения блоками try/except
try:
# Чтобы выбросить ошибку, используется raise
raise IndexError("Это ошибка индекса")
except IndexError as e:
2020-09-02 02:33:37 +03:00
pass # pass — это просто отсутствие оператора. Обычно здесь происходит восстановление после ошибки.
2014-09-09 19:49:29 +04:00
except (TypeError, NameError):
2020-09-02 02:33:37 +03:00
pass # Несколько исключений можно обработать вместе, если нужно.
else: # Необязательное выражение. Должно следовать за последним блоком except
print("Всё хорошо!") # Выполнится, только если не было никаких исключений
finally: # Выполнить при любых обстоятельствах
print("Мы можем очистить ресурсы здесь")
# Вместо try/finally чтобы очистить ресурсы, можно использовать оператор with
with open("myfile.txt") as f:
for line in f:
print(line)
# Запись в файл
contents = {"aa": 12, "bb": 21}
with open("myfile1.txt", "w+") as file:
file.write(str(contents)) # Записывает строку в файл
with open("myfile2.txt", "w+") as file:
file.write(json.dumps(contents)) # Записывает объект в файл
# Чтение из файла
with open('myfile1.txt', "r+") as file:
contents = file.read() # Читает строку из файла
print(contents)
# print: {"aa": 12, "bb": 21}
with open('myfile2.txt', "r+") as file:
contents = json.load(file) # Читает объект json из файла
print(contents)
# print: {"aa": 12, "bb": 21}
2014-09-09 19:49:29 +04:00
# Python предоставляет фундаментальную абстракцию,
2020-09-02 02:33:37 +03:00
# которая называется итерируемым объектом (Iterable).
2014-09-09 19:49:29 +04:00
# Итерируемый объект — это объект, который воспринимается как последовательность.
# Объект, который возвратила функция range(), итерируемый.
2020-09-02 02:33:37 +03:00
2014-09-09 19:49:29 +04:00
filled_dict = {"one": 1, "two": 2, "three": 3}
our_iterable = filled_dict.keys()
2020-09-02 02:33:37 +03:00
print(our_iterable) # => dict_keys(['one', 'two', 'three']). Это объект, реализующий интерфейс Iterable
2014-09-09 19:49:29 +04:00
# Мы можем проходить по нему циклом.
for i in our_iterable:
2020-09-02 02:33:37 +03:00
print(i) # Выводит one, two, three
2014-09-09 19:49:29 +04:00
# Н о мы не можем обращаться к элементу по индексу.
2020-09-02 02:33:37 +03:00
our_iterable[1] # Выбрасывает ошибку TypeError
2014-09-09 19:49:29 +04:00
# Итерируемый объект знает, как создавать итератор.
our_iterator = iter(our_iterable)
# Итератор может запоминать состояние при проходе по объекту.
2020-09-02 02:33:37 +03:00
# Мы получаем следующий объект, вызывая функцию next().
next(our_iterator) # => "one"
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Он сохраняет состояние при вызове next().
next(our_iterator) # => "two"
next(our_iterator) # => "three"
2014-09-09 19:49:29 +04:00
# Возвратив все данные, итератор выбрасывает исключение StopIterator
2020-09-02 02:33:37 +03:00
next(our_iterator) # Выбрасывает исключение StopIteration
# Мы можем проходить по нему циклом.
our_iterator = iter(our_iterable)
for i in our_iterator:
print(i) # Выводит one, two, three
2014-09-09 19:49:29 +04:00
2014-09-19 23:54:06 +04:00
# Вы можете получить сразу все элементы итератора, вызвав на нём функцию list().
2020-09-02 02:33:37 +03:00
list(our_iterable) # => Возвращает ["one", "two", "three"]
list(our_iterator) # => Возвращает [] потому что состояние сохраняется
2014-09-09 19:49:29 +04:00
####################################################
## 4. Функции
####################################################
# Используйте def для создания новых функций
def add(x, y):
print("x равен %s, а y равен %s" % (x, y))
2020-09-02 02:33:37 +03:00
return x + y # Возвращайте результат с помощью ключевого слова return
2014-09-09 19:49:29 +04:00
# Вызов функции с аргументами
2020-09-02 02:33:37 +03:00
add(5, 6) # => Выводит "x равен 5, а y равен 6" и возвращает 11
2014-09-09 19:49:29 +04:00
# Другой способ вызова функции — вызов с именованными аргументами
2020-09-02 02:33:37 +03:00
add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
2014-09-09 19:49:29 +04:00
2015-01-18 01:00:06 +03:00
# Вы можете определить функцию, принимающую переменное число аргументов
2014-09-09 19:49:29 +04:00
def varargs(*args):
return args
2020-09-02 02:33:37 +03:00
varargs(1, 2, 3) # => (1,2,3)
2014-09-09 19:49:29 +04:00
2015-01-18 01:00:06 +03:00
# А также можете определить функцию, принимающую переменное число
2014-09-09 19:49:29 +04:00
# именованных аргументов
def keyword_args(**kwargs):
return kwargs
# Вызовем эту функцию и посмотрим, что из этого получится
2020-09-02 02:33:37 +03:00
keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
2014-09-09 19:49:29 +04:00
# Если хотите, можете использовать о б а способа одновременно
def all_the_args(*args, **kwargs):
print(args)
print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) выводит:
(1, 2)
{"a": 3, "b": 4}
"""
# Вызывая функции, можете сделать наоборот!
2015-01-18 01:00:06 +03:00
# Используйте символ * для распаковки кортежей и ** для распаковки словарей
2014-09-09 19:49:29 +04:00
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
2020-09-02 02:33:37 +03:00
all_the_args(*args) # эквивалентно all_the_args(1, 2, 3, 4)
all_the_args(**kwargs) # эквивалентно all_the_args(a=3, b=4)
all_the_args(*args, **kwargs) # эквивалентно all_the_args(1, 2, 3, 4, a=3, b=4)
# Возврат нескольких значений (с назначением кортежей)
def swap(x, y):
return y, x # Возвращает несколько значений в виде кортежа без скобок.
# (Примечание: скобки исключены, но могут быть включены)
x = 1
y = 2
x, y = swap(x, y) # => x = 2, y = 1
# (x, y) = swap(x,y) # Снова, скобки были исключены, но могут быть включены.
2014-09-09 19:49:29 +04:00
# Область определения функций
x = 5
2020-09-02 02:33:37 +03:00
def set_x(num):
2014-09-09 19:49:29 +04:00
# Локальная переменная x — это не то же самое, что глобальная переменная x
2020-09-02 02:33:37 +03:00
x = num # => 43
print(x) # => 43
def set_global_x(num):
2014-09-09 19:49:29 +04:00
global x
2020-09-02 02:33:37 +03:00
print(x) # => 5
x = num # Глобальная переменная x теперь равна 6
print(x) # => 6
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
set_x(43)
set_global_x(6)
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Python имеет функции первого класса
2014-09-09 19:49:29 +04:00
def create_adder(x):
def adder(y):
return x + y
return adder
add_10 = create_adder(10)
2020-09-02 02:33:37 +03:00
add_10(3) # => 13
2014-09-09 19:49:29 +04:00
# Также есть и анонимные функции
2020-09-02 02:33:37 +03:00
(lambda x: x > 2)(3) # => True
(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
2014-09-09 19:49:29 +04:00
# Есть встроенные функции высшего порядка
2020-09-02 02:33:37 +03:00
list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7]
# Для удобного отображения и фильтрации можно использовать списочные интерпретации
# Интерпретация списка сохраняет вывод в виде списка, который сам может быть вложенным списком
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
# Вы также можете создавать интерпретации множеств и словарей.
{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'}
{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
2014-09-09 19:49:29 +04:00
####################################################
2020-09-02 02:33:37 +03:00
## 5. Модули
2014-09-09 19:49:29 +04:00
####################################################
2020-09-02 02:33:37 +03:00
# Вы можете импортировать модули
import math
print(math.sqrt(16)) # => 4.0
# Вы можете получить определенные функции из модуля
from math import ceil, floor
print(ceil(3.7)) # => 4.0
print(floor(3.7)) # => 3.0
# Вы можете импортировать все функции из модуля.
# Предупреждение: это не рекомендуется
from math import *
# Вы можете сократить имена модулей
import math as m
math.sqrt(16) == m.sqrt(16) # => True
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Модули Python - это обычные файлы Python. Вы
# можете писать свои собственные и импортировать их. Имя
# модуля совпадает с именем файла.
# Вы можете узнать, какие функции и атрибуты
# определены в модуле.
import math
dir(math)
# Если у вас есть скрипт Python с именем math.py в той же папке,
# что и ваш текущий скрипт, файл math.py будет
# будет загружен вместо встроенного модуля Python.
# Это происходит потому, что локальная папка имеет приоритет
# над встроенными библиотеками Python.
####################################################
## 6. Классы
####################################################
# Мы используем оператор class для создания класса
class Human:
# Атрибут класса. Он используется всеми экземплярами этого класса
species = "Гомосапиенс"
2014-09-09 19:49:29 +04:00
# Обычный конструктор, вызывается при инициализации экземпляра класса
# Обратите внимание, что двойное подчёркивание в начале и в конце имени
# означает объекты и атрибуты, которые используются Python, но находятся
# в пространствах имён, управляемых пользователем.
2020-09-02 02:33:37 +03:00
# Методы (или объекты или атрибуты), например:
# __init__ , __str__ , __repr__ и т. д. называются специальными методами.
2014-09-09 19:49:29 +04:00
# Н е придумывайте им имена самостоятельно.
def __init__ (self, name):
2020-09-02 02:33:37 +03:00
# Присваивание значения аргумента атрибуту
2014-09-09 19:49:29 +04:00
self.name = name
2020-09-02 02:33:37 +03:00
# Инициализация свойства
self._age = 0
2014-09-09 19:49:29 +04:00
# Метод экземпляра. В с е методы принимают self в качестве первого аргумента
def say(self, msg):
return "{name}: {message}".format(name=self.name, message=msg)
2020-09-02 02:33:37 +03:00
# Другой метод экземпляра
def sing(self):
return 'йо... йо... проверка микрофона... раз, два... раз, два...'
2014-09-09 19:49:29 +04:00
# Метод класса разделяется между всеми экземплярами
# Они вызываются с указыванием вызывающего класса в качестве первого аргумента
@classmethod
def get_species(cls):
return cls.species
# Статический метод вызывается без ссылки на класс или экземпляр
@staticmethod
def grunt():
return "*grunt*"
2020-09-02 02:33:37 +03:00
# property похоже на геттер.
# Оно превращает метод age() в одноименный атрибут только для чтения.
# Однако нет необходимости писать тривиальные геттеры и сеттеры в Python.
@property
def age(self):
return self._age
# Это позволяет установить свойство
@age .setter
def age(self, age):
self._age = age
# Это позволяет удалить свойство
@age .deleter
def age(self):
del self._age
# Когда интерпретатор Python читает исходный файл, он выполняет весь е г о код.
# Проверка __name__ гарантирует, что этот блок кода выполняется только тогда, когда
# этот модуль - это основная программа.
if __name__ == '__main__':
# Инициализация экземпляра класса
i = Human(name="Иван")
i.say("привет") # Выводит: "Иван: привет"
j = Human("Пётр")
j.say("привет") # Выводит: "Пётр: привет"
# i и j являются экземплярами типа Human, или другими словами: они являются объектами Human
# Вызов метода класса
i.say(i.get_species()) # "Иван: Гомосапиенс"
# Изменение разделяемого атрибута
Human.species = "Неандертальец"
i.say(i.get_species()) # => "Иван: Неандертальец"
j.say(j.get_species()) # => "Пётр: Неандертальец"
# Вызов статического метода
print(Human.grunt()) # => "*grunt*"
# Невозможно вызвать статический метод с экземпляром объекта
# потому что i.grunt() автоматически поместит "self" (объект i) в качестве аргумента
print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
# Обновить свойство для этого экземпляра
i.age = 42
# Получить свойство
i.say(i.age) # => "Иван: 42"
j.say(j.age) # => "Пётр: 0"
# Удалить свойство
del i.age
# i.age # => это выбрасило бы ошибку AttributeError
####################################################
## 6.1 Наследование
####################################################
# Наследование позволяет определять новые дочерние классы, которые наследуют методы и
# переменные от своего родительского класса.
# Используя класс Human, определенный выше как базовый или родительский класс, мы можем
# определить дочерний класс Superhero, который наследует переменные класса, такие как
# "species", "name" и "age", а также методы, такие как "sing" и "grunt" из класса Human,
# но также может иметь свои уникальные свойства.
# Чтобы воспользоваться преимуществами модульности по файлам, вы можете поместить
# вышеперечисленные классы в их собственные файлы, например, human.py
# Чтобы импортировать функции из других файлов, используйте следующий формат
# from "имя-файла-без-расширения" import "функция-или-класс"
from human import Human
# Укажите родительский класс(ы) как параметры определения класса
class Superhero(Human):
# Если дочерний класс должен наследовать все определения родителя без каких-либо
# изменений, вы можете просто использовать ключевое слово pass (и ничего больше),
# но в этом случае оно закомментировано, чтобы разрешить уникальный дочерний класс:
# pass
# Дочерние классы могут переопределять атрибуты своих родителей
species = 'Сверхчеловек'
# Дочерние классы автоматически наследуют конструктор родительского класса, включая
# е г о аргументы, но также могут определять дополнительные аргументы или определения
# и переопределять е г о методы, такие как конструктор класса.
# Этот конструктор наследует аргумент "name" от класса "Human"
# и добавляет аргументы "superpower" и "movie":
def __init__ (self, name, movie=False,
superpowers=["сверхсила", "пуленепробиваемость"]):
# добавить дополнительные атрибуты класса:
self.fictional = True
self.movie = movie
# помните о б изменяемых значениях по умолчанию,
# поскольку значения по умолчанию являются общими
self.superpowers = superpowers
# Функция "super" позволяет вам получить доступ к методам родительского класса,
# которые переопределяются дочерним, в данном случае, методом __init__ .
# Это вызывает конструктор родительского класса:
super().__init__(name)
# переопределить метод sing
def sing(self):
return 'Бам, бам, БАМ!'
# добавить дополнительный метод экземпляра
def boast(self):
for power in self.superpowers:
print("Я обладаю силой '{pow}'!".format(pow=power))
if __name__ == '__main__':
sup = Superhero(name="Тик")
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Проверка типа экземпляра
if isinstance(sup, Human):
print('Я человек')
if type(sup) is Superhero:
print('Я супергерой')
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Получить порядок поиска разрешения метода (MRO),
# используемый как getattr(), так и super()
# Этот атрибут является динамическим и может быть обновлен
print(Superhero.__mro__) # => (< class ' __main__ . Superhero ' > ,
# => < class ' human . Human ' > , < class ' object ' > )
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Вызывает родительский метод, но использует свой собственный атрибут класса
print(sup.get_species()) # => Сверхчеловек
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Вызов переопределенного метода
print(sup.sing()) # => Бам, бам, БАМ!
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# Вызывает метод из Human
sup.say('Ложка') # => Тик: Ложка
# Метод вызова, существующий только в Superhero
sup.boast() # => Я обладаю силой 'сверхсила'!
# => Я обладаю силой 'пуленепробиваемость'!
# Атрибут унаследованного класса
sup.age = 31
print(sup.age) # => 31
# Атрибут, который существует только в Superhero
print('Достоин ли я Оскара? ' + str(sup.movie))
2014-09-09 19:49:29 +04:00
####################################################
2020-09-02 02:33:37 +03:00
## 6.2 Множественное наследование
2014-09-09 19:49:29 +04:00
####################################################
2020-09-02 02:33:37 +03:00
# Eще одно определение класса
# bat.py
class Bat:
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
species = 'Летучая мышь'
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
def __init__ (self, can_fly=True):
self.fly = can_fly
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# В этом классе также есть метод say
def say(self, msg):
msg = '... ... ...'
return msg
2014-09-09 19:49:29 +04:00
2020-09-02 02:33:37 +03:00
# И свой метод тоже
def sonar(self):
return '))) ... ((('
if __name__ == '__main__':
b = Bat()
print(b.say('привет'))
print(b.fly)
# И еще одно определение класса, унаследованное от Superhero и Bat
# superhero.py
from superhero import Superhero
from bat import Bat
# Определите Batman как дочерний класс, унаследованный от Superhero и Bat
class Batman(Superhero, Bat):
def __init__ (self, *args, * *kwargs):
# Обычно для наследования атрибутов необходимо вызывать super:
# super(Batman, self).__init__(*args, **kwargs)
# Однако здесь мы имеем дело с множественным наследованием, а super()
# работает только с о следующим базовым классом в списке MRO.
# Поэтому вместо этого мы вызываем __init__ для всех родителей.
# Использование *args и * *kwargs обеспечивает чистый способ передачи
# аргументов, когда каждый родитель "очищает слой луковицы".
Superhero.__init__(self, 'анонимный', movie=True,
superpowers=['Богатый'], *args, * *kwargs)
Bat.__init__(self, *args, can_fly=False, * *kwargs)
# переопределить значение атрибута name
self.name = 'Грустный Бен Аффлек'
def sing(self):
return 'на на на на на бэтмен!'
if __name__ == '__main__':
sup = Batman()
# Получить порядок поиска разрешения метода (MRO),
# используемый как getattr(), так и super()
# Этот атрибут является динамическим и может быть обновлен
print(Batman.__mro__) # => (< class ' __main__ . Batman ' > ,
# => < class ' superhero . Superhero ' > ,
# => < class ' human . Human ' > ,
# => < class ' bat . Bat ' > , < class ' object ' > )
# Вызывает родительский метод, но использует свой собственный атрибут класса
print(sup.get_species()) # => Сверхчеловек
# Вызов переопределенного метода
print(sup.sing()) # => на на на на на бэтмен!
# Вызывает метод из Human, потому что порядок наследования имеет значение
sup.say('Я согласен') # => Грустный Бен Аффлек: Я согласен
# Вызов метода, существующий только во втором родителе
print(sup.sonar()) # => ))) ... (((
# Атрибут унаследованного класса
sup.age = 100
print(sup.age) # => 100
# Унаследованный атрибут от второго родителя,
# значение по умолчанию которого было переопределено.
print('М о г у ли я летать? ' + str(sup.fly)) # => М о г у ли я летать? False
2014-09-09 19:49:29 +04:00
####################################################
## 7. Дополнительно
####################################################
# Генераторы помогут выполнить ленивые вычисления
def double_numbers(iterable):
for i in iterable:
yield i + i
2020-09-02 02:33:37 +03:00
# Генераторы эффективны с точки зрения памяти, потому что они загружают только данные,
# необходимые для обработки следующего значения в итерации.
# Это позволяет им выполнять операции с недопустимо большими диапазонами значений.
# ПРИМЕЧАНИЕ: "range" заменяет "xrange" в Python 3.
for i in double_numbers(range(1, 900000000)): # "range" - генератор.
2014-09-09 19:49:29 +04:00
print(i)
if i >= 30:
break
2020-09-02 02:33:37 +03:00
# Так же, как вы можете создать интерпретации списков, вы можете создать и
# интерпретации генераторов.
values = (-x for x in [1,2,3,4,5])
for x in values:
print(x) # Выводит -1 -2 -3 -4 -5
# Вы также можете преобразовать интерпретацию генератора непосредственно в список.
values = (-x for x in [1,2,3,4,5])
gen_to_list = list(values)
print(gen_to_list) # => [-1, -2, -3, -4, -5]
2014-09-09 19:49:29 +04:00
# Декораторы
2020-09-02 02:33:37 +03:00
# В этом примере "beg" оборачивает "say".
# Если say_please равно True, он изменит возвращаемое сообщение.
2014-09-09 19:49:29 +04:00
from functools import wraps
def beg(target_function):
@wraps (target_function)
def wrapper(*args, **kwargs):
msg, say_please = target_function(*args, **kwargs)
if say_please:
2020-09-02 02:33:37 +03:00
return "{} {}".format(msg, "Пожалуйста! У меня нет денег :(")
2014-09-09 19:49:29 +04:00
return msg
return wrapper
@beg
def say(say_please=False):
msg = "Вы не купите мне пива?"
return msg, say_please
2020-09-02 02:33:37 +03:00
print(say()) # Вы не купите мне пива?
print(say(say_please=True)) # Вы не купите мне пива? Пожалуйста! У меня нет денег :(
2014-09-09 19:49:29 +04:00
```
## Хотите ещё?
### Бесплатные онлайн-материалы
2020-09-02 02:33:37 +03:00
* [Automate the Boring Stuff with Python ](https://automatetheboringstuff.com )
2014-09-09 19:49:29 +04:00
* [Ideas for Python Projects ](http://pythonpracticeprojects.com )
* [Официальная документация ](http://docs.python.org/3/ )
* [Hitchhiker's Guide to Python ](http://docs.python-guide.org/en/latest/ )
2020-09-02 02:33:37 +03:00
* [Python Course ](http://www.python-course.eu/index.php )
* [First Steps With Python ](https://realpython.com/learn/python-first-steps/ )
* [A curated list of awesome Python frameworks, libraries and software ](https://github.com/vinta/awesome-python )
* [30 Python Language Features and Tricks You May Not Know About ](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html )
* [Official Style Guide for Python ](https://www.python.org/dev/peps/pep-0008/ )
* [Python 3 Computer Science Circles ](http://cscircles.cemc.uwaterloo.ca/ )
* [Dive Into Python 3 ](http://www.diveintopython3.net/index.html )
* [A Crash Course in Python for Scientists ](http://nbviewer.jupyter.org/gist/anonymous/5924718 )
* [Python Tutorial for Intermediates ](https://pythonbasics.org/ )
* [Build a Desktop App with Python ](https://pythonpyqt.com/ )
2014-09-09 19:49:29 +04:00