Советы и лучшие практики
PEP 8 — стиль кода
- Отступы: 4 пробела (не табуляция)
- Максимум 79 символов в строке
- Пустые строки между функциями (2) и внутри класса (1)
- Пробелы вокруг операторов:
a = b + c, не a=b+c
- Импорты: стандартные → сторонние → локальные
Pythonic-идиомы
# Swap
a, b = b, a
# Проверка на None
if value is None: ... # условие
# Пустая коллекция → False
if not items: ... # условие
# Тернарник
status = "чёт" if n % 2 == 0 else "нечёт"
# Распаковка
first, *rest = [1, 2, 3, 4] # first=1, rest=[2,3,4]
# enumerate с индексом
for i, val in enumerate(lst): ... # цикл по элементам
# zip для параллельной итерации
for name, age in zip(names, ages): ... # цикл по элементам
# any / all
if any(x > 0 for x in lst): ... # условие
# Вхождение в диапазон
if 0 <= score <= 100: ... # условие
# Словарь с get
value = d.get("key", default) # безопасный доступ со значением по умолчанию
# Множественные сравнения
if a == b == c: ... # условие
Частые ошибки
# 1. Изменяемый аргумент по умолчанию
def add(item, lst=[]):
lst.append(item) # добавление в конец
return lst # возврат значения
def add(item, lst=None):
if lst is None: # условие
lst = [] # инициализация списка
lst.append(item) # добавление в конец
return lst # возврат значения
# 2. Использование is с числами/строками
# is — для None и True/False. == — для всего остального
# 3. Выход за границы списка
items = [1, 2, 3] # инициализация списка
try: # начало блока с обработкой исключений
items[10]
except IndexError: # обработка исключения
...
# 4. Изменение списка во время итерации
# ПЛОХО: for item in lst: lst.remove(item)
# ХОРОШО: [x for x in lst if condition]
# 5. Исключение в except без указания типа
# ПЛОХО: except:
# ХОРОШО: except ValueError:
# 6. global — обычно не нужно
# ПЛОХО: def f(): global x; x += 1
# 7. range(len(lst)) — используйте enumerate
Производительность
# Генераторы быстрее списков, если не нужен весь результат
sum(x**2 for x in range(1000000)) # сумма
sum([x**2 for x in range(1000000)]) # сумма
# local variables быстрее global
def func():
local_math = math.sqrt # математическая функция
for i in range(1000): # цикл по элементам
local_math(i)
# join быстрее + для строк
# ПЛОХО: s = ""; for p in parts: s += p
# ХОРОШО: s = "".join(parts)
# set быстрее list для in
# in set: O(1), in list: O(n)
lookup = set(items) # преобразование в множество
if value in lookup: ... # условие
# collections.deque быстрее list для pop(0) / insert(0, x)
from collections import deque # импорт специализированных коллекций
dq = deque([1, 2, 3]) # двусторонняя очередь
dq.popleft() # O(1)
Полезные однострочники
# Уникальные элементы
unique = list(set(items)) # преобразование в список
# Разворот строки/списка
reversed_s = s[::-1] # присваивание
# Палиндром
is_palindrome = s == s[::-1]
# Плоский список из вложенного
flat = [x for sub in nested for x in sub] # списковое включение
# Транспонирование матрицы
transposed = list(zip(*matrix)) # преобразование в список
# Самое частое значение
from statistics import mode # импорт модуля
most_common = mode(data) # присваивание
# Чтение файла в список строк
lines = open("file.txt").read().splitlines() # открытие файла
Инструменты
- black — автоформатирование кода
- ruff — быстрый линтер (замена flake8, isort)
- mypy — проверка типов
- pre-commit — хуки перед коммитом
- pytest — тестирование
- poetry / uv — управление зависимостями
- ipdb — отладка (import ipdb; ipdb.set_trace())
Ресурсы