Python QA

Ответы на частые вопросы по Python

В чем разница между list и tuple?

list изменяемый, поддерживает добавление/удаление; tuple неизменяемый, можно хешировать и использовать в ключах словарей.

lst = [1, 2]; lst.append(3)
tpl = (1, 2, 3)  # tpl[0] = 5 -> TypeError
list tuple список кортеж

Что такое dict и какова амортизационная сложность доступа?

dict — хеш-таблица; доступ/вставка/удаление в среднем O(1), в худшем O(n).

d = {'a': 1}; d['b'] = 2; val = d['a']
dict словарь хеш hash

Чем отличается set от list?

set хранит уникальные элементы без порядка и дает O(1) поиск по хешу; list упорядочен и допускает дубликаты.

s = {1, 2, 2}; len(s) == 2
lst = [1, 2, 2]  # длина 3
set множество list поиск

Как работает list comprehension?

Синтаксический сахар для генерации списка в одной строке с фильтрами и вложенными циклами.

[x*x for x in range(5) if x % 2 == 0]  # [0, 4, 16]
list comprehension генератор списка [] for

В чем отличие генератора от списка?

Генератор ленивый и не хранит все элементы в памяти; list хранит все сразу.

(x*x for x in range(10))  # генератор
list(x*x for x in range(10))  # сразу список
генератор generator list ленивый

Что такое итератор в Python?

Объект с __iter__ и __next__, выдающий элементы по одному и завершающийся StopIteration.

it = iter([1,2]); next(it)  # 1; next(it)  # 2; next(it) -> StopIteration
итератор __iter__ __next__ StopIteration

Что такое iterable?

Объект, по которому можно итерироваться (__iter__ или __getitem__ с индексом).

for ch in "abc": print(ch)
class C: __getitem__ = lambda self,i: (1 if i<3 else (_ for _ in ()).throw(StopIteration))
iterable __iter__ __getitem__ итерации

Разница между __iter__ и __next__?

__iter__ возвращает итератор; __next__ возвращает следующий элемент или StopIteration.

class C:
    def __iter__(self): return self
    def __next__(self): raise StopIteration
__iter__ __next__ StopIteration

Что такое GIL?

Global Interpreter Lock — мьютекс CPython, разрешающий байткод только одному потоку одновременно.

import threading
# CPU-bound в двух потоках не ускорится из-за GIL
GIL Global Interpreter Lock потоки

Когда GIL не мешает?

При I/O-bound задачах, при multiprocessing, либо когда C-расширения временно отпускают GIL.

requests.get(...) в нескольких потоках — параллельное I/O
multiprocessing.Pool для CPU-bound
GIL I/O multiprocessing C-extension

Разница threading и multiprocessing?

threading делит память и упирается в GIL; multiprocessing создает процессы с отдельной памятью, обходя GIL.

threading.Thread(target=io_task)
multiprocessing.Process(target=cpu_task)
threading multiprocessing GIL процессы

Когда использовать asyncio?

При множестве I/O-задач с малой нагрузкой CPU: сокеты, HTTP, файлы; не подходит для чистого CPU-bound.

async def main():
    async with aiohttp.ClientSession() as s:
        await s.get(url)
asyncio I/O await event loop

Разница async/await и threads?

async/await — кооперативная многозадачность в одном потоке; threads — системные потоки, планируются ОС.

await coro()  # не блокирует event loop
threading.Thread(target=func).start()
async await threads кооператив

Что такое декоратор?

Функция, принимающая функцию/метод и возвращающая обертку с доп. логикой.

def log(f):
    def wrap(*a, **k): print(f.__name__); return f(*a, **k)
    return wrap
@log
def hello(): pass
декоратор decorator @ обертка

Как сохранить метаданные функции при декорировании?

Использовать functools.wraps для копирования __name__, __doc__ и др.

from functools import wraps
@wraps(func)
def wrapper(*a, **k): ...
functools.wraps декоратор __name__ __doc__

Что такое контекстный менеджер?

Объект с __enter__/__exit__, гарантирующий освобождение ресурсов в блоке with.

with open('f.txt') as f:
    data = f.read()
контекстный менеджер __enter__ __exit__ with

Как написать контекстный менеджер без класса?

Через contextlib.contextmanager и генератор с yield.

from contextlib import contextmanager
@contextmanager
def cm():
    res = open('f'); yield res; res.close()
contextlib contextmanager with yield

Что делает itertools?

Быстрые итераторы для комбинаторики, группировки, бесконечных последовательностей.

from itertools import chain, product
list(chain([1,2],[3]))  # [1,2,3]
itertools комбинаторика chain product

В чем отличие shallow copy и deepcopy?

Shallow копирует контейнер, но вложенные ссылки общие; deepcopy рекурсивно копирует всё.

import copy
b = copy.copy(a)
c = copy.deepcopy(a)
shallow deepcopy copy вложенные

Что такое dataclass?

Синтаксический сахар для классов данных: автогенерация __init__, __repr__, сравнения.

from dataclasses import dataclass
@dataclass
class P: x:int; y:int
dataclass __init__ __repr__ fields

Зачем slots в классе?

__slots__ экономит память и ускоряет доступ, запрещая произвольные атрибуты (__dict__ не создается).

class P:
    __slots__ = ('x','y')
    def __init__(self,x,y): self.x=x; self.y=y
__slots__ память __dict__ класс

Отличие @staticmethod и @classmethod?

@staticmethod не получает self/cls; @classmethod получает cls и работает с классом/наследниками.

class C:
    @staticmethod
    def s(x): return x
    @classmethod
    def c(cls): return cls
staticmethod classmethod self cls

Разница между == и is?

== сравнивает значения (__eq__), is сравнивает идентичность (один объект).

a = [1]; b = [1]; a == b  # True; a is b  # False
== is __eq__ идентичность

Как работает хешируемость объекта?

Нужен __hash__ и неизменяемое состояние, чтобы hash(a)==hash(b) при a==b сохранялось.

hash((1,2))  # ок; hash([1,2]) -> TypeError
__hash__ __eq__ хешируемый неизменяемый

Как ловить и логировать исключения?

try/except; в except logger.exception или exc_info=True; освобождение ресурсов через finally/with.

try:
    1/0
except Exception:
    logger.exception("fail")
исключение try except логирование

Для чего нужен typing?

Подсказки типов для статпроверки (mypy/pyright), автодополнения и документации.

def add(x: int, y: int) -> int:
    return x + y
typing type hints mypy pyright

Что делает Protocol в typing?

Описывает структурный тип (duck typing) для статической проверки интерфейсов.

class R(Protocol):
    def read(self, n: int) -> str: ...
Protocol typing duck структурный

Разница MutableSequence и Sequence?

MutableSequence требует методы мутации; Sequence — только чтение/итерацию/len.

from collections.abc import MutableSequence, Sequence
MutableSequence Sequence ABC typing

Что такое PEP 8?

Стиль кода: отступ 4 пробела, длина строки 79/99, имена, пробелы вокруг операторов.

# хорошо: value = func(arg1, arg2)
# плохо: value=func( arg1,arg2 )
PEP 8 стиль отступы длина строки

Чем отличается venv от virtualenv?

venv встроен (3.3+); virtualenv старше, часто быстрее создаёт окружение, имеет доп. фичи.

python -m venv .venv
source .venv/bin/activate
venv virtualenv окружение env

Как закрепить зависимости?

requirements.txt или lock-файлы (poetry.lock/Pipfile.lock) для воспроизводимости версий.

pip freeze > requirements.txt
pip install -r requirements.txt
requirements poetry pipenv зависимости

Что такое pip freeze?

Команда выводит установленные пакеты и версии; часто используют для requirements.txt.

pip freeze > requirements.txt
pip freeze requirements зависимости

Разница между pip и pipx?

pip ставит в текущее окружение; pipx ставит CLI-инструменты изолированно и добавляет в PATH.

pipx install black
black --version
pipx pip CLI изолированно

Как работать с файлами безопасно?

Использовать with open(...) для гарантии закрытия; указывать encoding; ловить IOErrors.

with open('data.txt', 'r', encoding='utf-8') as f:
    data = f.read()
open with encoding файл

Что такое pathlib?

ООП-обертка путей с удобными методами и оператором / для join.

from pathlib import Path
p = Path('data')/'file.txt'
text = p.read_text()
pathlib Path путь файлы

Как сериализовать в JSON?

json.dumps/json.dump; для нестандартных типов использовать default или приведение.

import json
json.dumps({'x': 1})
json dumps dump сериализация

Как сериализовать в pickle?

pickle.dump/load; не грузить непроверенные данные из-за RCE рисков.

import pickle
pickle.dump(obj, open('f.pkl','wb'))
pickle dump load сериализация

Когда выбирать csv vs json?

CSV для плоских таблиц; JSON для вложенных структур. CSV компактнее, но без вложенности.

import csv
with open('f.csv','w',newline='') as f: csv.writer(f).writerow(['a',1])
csv json табличные вложенность

Как измерить время выполнения?

Использовать time.perf_counter; можно завернуть в контекст/декоратор.

import time
start = time.perf_counter(); ...; dt = time.perf_counter()-start
perf_counter время тайминг benchmark

Как профилировать CPU?

cProfile + pstats/snakeviz; для строк — line_profiler; для async — yappi/py-spy.

python -m cProfile -o out.prof script.py
snakeviz out.prof
cProfile профилирование CPU snakeviz

Как профилировать память?

tracemalloc, objgraph, memory_profiler для строк.

import tracemalloc
tracemalloc.start()
# ...
print(tracemalloc.get_traced_memory())
tracemalloc memory objgraph память

Что такое functools.lru_cache?

Декоратор мемоизации с ограничением размера и счётчиками hit/miss.

from functools import lru_cache
@lru_cache(maxsize=128)
def fib(n): ...
lru_cache functools кэш мемоизация

Как писать тесты в pytest?

Файлы test_*.py, функции test_*; фикстуры через @pytest.fixture, параметризация через parametrize.

def test_sum():
    assert 1+2 == 3
pytest тест fixture parametrize

Чем отличается assertRaises в unittest?

Контекст/декоратор, проверяющий, что код поднимает ожидаемое исключение.

with self.assertRaises(ValueError):
    int('abc')
unittest assertRaises исключение тест

Как мокать в тестах?

Использовать unittest.mock: patch/MagicMock/autospec/side_effect; патчить точку использования.

from unittest.mock import patch
with patch('pkg.mod.func', return_value=1): ...
mock patch MagicMock тест

Что такое dependency injection в Python?

Передача зависимостей через параметры/конструктор вместо жестких импортов, упрощает тестирование и подмены.

def handler(repo: Repo): repo.save(...)
handler(MockRepo())
dependency injection DI зависимости тест

Как работают property?

property создает дескриптор для геттеров/сеттеров, позволяя вызывать метод как атрибут.

class P:
    @property
    def x(self): return 1
property дескриптор getter setter

Что такое дескриптор?

Объект с __get__/__set__/__delete__, контролирующий доступ к атрибуту.

class D:
    def __get__(self, obj, owner): return 42
class C: x = D()
дескриптор __get__ __set__ __delete__

Как работает super()?

super ищет следующий класс в MRO и делегирует вызов.

class A: def f(self): print('A')
class B(A):
    def f(self): super().f(); print('B')
super MRO наследование __mro__

Что такое MRO?

Method Resolution Order — порядок поиска атрибутов (C3-линеаризация).

C.__mro__ показывает порядок
MRO наследование C3 __mro__

Чем отличается старый и новый стиль классов?

В 3.x все классы — новый стиль (наследуются от object); в 2.x нужно было явно наследоваться.

class A: pass  # уже новый стиль в 3.x
новый стиль object класс 2.x

Как работает garbage collector в CPython?

Подсчет ссылок + поколенческий GC для циклов (поколения 0/1/2).

import gc; gc.get_threshold()
garbage collector подсчет ссылок поколения циклы

Когда вызывать gc.collect()?

Редко; вручную при контролируемых пиках/циклах или профилировании.

import gc
gc.collect()
gc.collect GC сборщик циклы

Что такое weakref?

Слабые ссылки не увеличивают счётчик и позволяют GC собрать объект; полезно для кэшей.

import weakref
w = weakref.ref(obj)
weakref слабая ссылка кэш

Как работают map/filter/reduce?

map применяет функцию, filter отбирает по предикату, reduce сворачивает в одно значение.

list(map(str, [1,2]))
list(filter(lambda x: x%2, [1,2,3]))
map filter reduce functools

Чем отличаются *args и **kwargs?

*args собирает позиционные аргументы, **kwargs — именованные.

def f(*a, **k): print(a, k)
f(1,2,x=3)
*args **kwargs аргументы функция

Зачем нужен оператор := (walrus)?

Позволяет присвоить и использовать значение внутри выражения, снижая дублирование.

if (n := len(data)) > 0: print(n)
walrus := присваивание выражение

Что делает typing.NamedTuple?

Именованный tuple с полями, неизменяемый и хешируемый.

from typing import NamedTuple
class P(NamedTuple): x:int; y:int
NamedTuple typing tuple поля

Разница между bytes и str?

str — Unicode, bytes — сырые байты; преобразование через encode/decode.

b = 'привет'.encode('utf-8'); s = b.decode('utf-8')
bytes str encode decode

Как сравнить два dict по ключам/значениям?

dict1 == dict2 сравнивает ключи и значения; подмножества — через сравнение sets of items/keys.

d1 == d2
set(d1.items()) <= set(d2.items())
dict сравнение keys items

Что делает enumerate?

Итерирует с парами (index, value); удобнее range(len(...)).

for i, v in enumerate(['a','b']): print(i, v)
enumerate индекс итерация

Как перевернуть список?

slicing seq[::-1] или reversed(seq); in-place — list.reverse().

lst[::-1]
lst.reverse()
reverse reversed slicing список

Чем отличается sorted от list.sort?

sorted возвращает новый список; list.sort сортирует на месте и возвращает None.

sorted(lst)
lst.sort()
sorted sort in-place список

Как сортировать по ключу?

Указать key=функция, можно reverse=True.

sorted(users, key=lambda u: u.age, reverse=True)
sorted key lambda reverse

Что делает zip?

Комбинирует элементы итерируемых в кортежи по позиции, обрывается по кратчайшему.

list(zip([1,2],["a","b","c"]))  # [(1,'a'),(2,'b')]
zip итерация кортежи

Как распаковать коллекции в параметры?

* для позиционных, ** для именованных при вызове функции.

f(*[1,2], **{'x':3})
распаковка * ** аргументы

Что такое f-строки?

Форматирование через f"...{expr}...", быстро и читаемо, поддерживает выражения.

name = 'Bob'; f"Hi {name}"
f-строка format интерполяция

Разница format и f-строки?

f-строки короче и быстрее; str.format гибче для динамических шаблонов.

"{x}".format(x=1)
f"{1+1}"
format f-string строка

Как округлять числа правильно?

round(x, n) — банковское округление; для денег лучше Decimal.quantize.

from decimal import Decimal
Decimal('1.235').quantize(Decimal('0.01'))
round Decimal quantize округление

Что такое Decimal?

Десятичная арифметика с контролем точности/округления, полезна для денег.

from decimal import Decimal, getcontext
getcontext().prec = 28
Decimal('0.1') + Decimal('0.2')
Decimal деньги точность округление

Как работать с датами?

datetime/date/time/timedelta; таймзоны — zoneinfo/pytz; формат/парсинг через strftime/strptime.

from datetime import datetime
now = datetime.now().strftime('%Y-%m-%d')
datetime timedelta zoneinfo strftime

Что делает collections.Counter?

Считает частоты элементов, есть most_common и арифметика счетчиков.

from collections import Counter
Counter('abba').most_common(1)
Counter collections частоты most_common

Что такое OrderedDict и нужно ли в 3.7+?

Сохраняет порядок вставки; dict в 3.7+ тоже упорядочен, но OrderedDict дает move_to_end и др.

from collections import OrderedDict
od = OrderedDict(); od['a']=1; od.move_to_end('a')
OrderedDict dict порядок move_to_end

Что такое deque?

Двусторонняя очередь, O(1) добавление/удаление с концов.

from collections import deque
d = deque([1,2]); d.appendleft(0)
deque двусторонняя очередь collections

Когда использовать heapq?

Для приоритетных очередей/top-k; push/pop O(log n).

import heapq
h=[]; heapq.heappush(h, 3); heapq.heappush(h,1); heapq.heappop(h)
heapq куча приоритет top k

Как найти top-k без полной сортировки?

heapq.nlargest/nsmallest быстрее полной сортировки при малом k.

heapq.nlargest(3, data)
top-k nlargest heapq сортировка

Что делает bisect?

Бинарный поиск позиции вставки в отсортированной последовательности.

import bisect
idx = bisect.bisect_left([1,3,5], 4)
bisect бинарный поиск вставка отсортировано

Зачем нужен math.isclose?

Сравнивает float с учетом относит./абсолютной погрешности.

math.isclose(0.1+0.2, 0.3, rel_tol=1e-9)
isclose float погрешность math

Разница между == и is для NaN?

NaN != NaN по ==; is сравнивает объект; использовать math.isnan.

import math
math.isnan(float('nan'))
NaN == is isnan

Что такое asyncio.gather?

Параллельный запуск корутин с ожиданием всех; результаты в порядке аргументов.

await asyncio.gather(coro1(), coro2())
asyncio gather корутина параллельно

Как таймаутить корутину?

asyncio.wait_for(coro, timeout) или комбинация first_completed.

await asyncio.wait_for(coro(), timeout=1.0)
timeout wait_for asyncio корутина

Чем отличается asyncio.create_task и await?

create_task планирует корутину конкурентно; await ждет завершения.

task = asyncio.create_task(coro()); await task
create_task await asyncio корутина

Как работать с сигналами в Python?

signal.signal для обработчиков; ограничения на Windows; в asyncio add_signal_handler (не Windows).

import signal
signal.signal(signal.SIGINT, handler)
signal SIGINT SIGTERM обработчик

Как обрабатывать аргументы командной строки?

argparse (stdlib) или click/typer; для простого — sys.argv.

import argparse
p=argparse.ArgumentParser(); p.add_argument('--x'); args=p.parse_args()
argparse CLI аргументы sys.argv

Что такое pathlib.Path.glob?

Поиск файлов по шаблону (включая ** для рекурсии).

for p in Path('.').glob('**/*.py'): print(p)
glob pathlib шаблон файлы

Чем отличается os.path и pathlib?

pathlib — ООП API с / оператором; os.path — процедурные функции.

Path('a')/'b'
os.path.join('a','b')
os.path pathlib путь API

Как работать с окружением?

os.environ для чтения/установки; dotenv для загрузки .env; не хранить секреты в коде.

import os
os.environ.get('TOKEN')
os.environ .env переменные окружения секреты

Что такое logging.basicConfig?

Быстрая настройка логирования: уровень, формат, хендлеры.

import logging
logging.basicConfig(level=logging.INFO)
logging basicConfig логирование уровень

Как логировать tracebacks?

logger.exception или logger.error(..., exc_info=True); в stdout — traceback.print_exc.

try:
    1/0
except Exception:
    logger.exception('fail')
traceback logger.exception exc_info ошибка

Что делает warnings.filterwarnings?

Управляет показом предупреждений (ignore/error/default) по категориям/модулям.

import warnings
warnings.filterwarnings('ignore', category=DeprecationWarning)
warnings filterwarnings предупреждения

Что такое Pydantic?

Валидация/парсинг данных по аннотациям типов, генерирует модели.

from pydantic import BaseModel
class User(BaseModel): name: str; age: int
pydantic валидация модели typing

Чем отличается FastAPI от Flask?

FastAPI асинхронный с автодокой/схемой; Flask минималистичный синхронный.

app = FastAPI(); @app.get('/') async def root(): return {'ok':True}
FastAPI Flask ASGI WSGI

Что такое WSGI и ASGI?

WSGI — синхронный протокол веб-приложений; ASGI — асинхронный, поддерживает WebSocket/фоновые задачи.

gunicorn (WSGI) vs uvicorn (ASGI)
WSGI ASGI веб протокол

Как выполнять SQL безопасно?

Параметризованные запросы, избегать конкатенации строк; для сложного использовать ORM.

cur.execute('SELECT * FROM t WHERE id=%s', (id_,))
SQL параметры инъекции ORM

Что такое ORM?

Object-Relational Mapping: отображение таблиц в классы; напр. SQLAlchemy, Django ORM.

class User(Base): __tablename__='users'; id=Column(Integer, primary_key=True)
ORM SQLAlchemy Django ORM таблицы

Что такое contextvars?

Контекстные переменные для изоляции состояния в async/greenlet, аналог thread-local.

from contextvars import ContextVar
user = ContextVar('user')
contextvars async context state

Как ограничить скорость запросов?

Токен-бакеты/семафоры/счетчики (Redis), задержки в клиентах.

sem = asyncio.Semaphore(5)
async with sem: await fetch()
rate limit throttle семафор Redis

Как безопасно хранить пароли?

Хешировать с солью (bcrypt/argon2/scrypt), не хранить в открытом виде.

bcrypt.hashpw(pwd, bcrypt.gensalt())
пароли bcrypt argon2 соль

Чем отличается deepcopy от copy.copy?

copy.copy — поверхностная копия; deepcopy копирует рекурсивно.

copy.copy(obj)
copy.deepcopy(obj)
deepcopy copy вложенные

Как работает __enter__/__exit__ в with?

__enter__ возвращает объект; __exit__ получает тип/значение/traceback ошибки и решает, подавлять ли её.

class CM:
    def __enter__(self): return self
    def __exit__(self, exc_type, exc, tb): return False
__enter__ __exit__ with контекст

Что такое monkey patching?

Динамическая подмена атрибутов/функций во время исполнения; удобно в тестах, рискованно в проде.

module.func = lambda: 1
monkey patch подмена runtime тест

Как работают namedtuple и dataclass?

namedtuple — легкий неизменяемый tuple с именами; dataclass — полноценный класс с автогенерацией методов.

from collections import namedtuple
P = namedtuple('P','x y')
from dataclasses import dataclass
@dataclass
class D: x:int; y:int
namedtuple dataclass tuple класс

Что такое __all__ в модуле?

__all__ определяет, что экспортируется при from module import *.

__all__ = ['foo', 'Bar']
__all__ модуль export import *

Как работает __name__ == '__main__'?

Блок выполняется при прямом запуске скрипта, не при импорте.

if __name__ == '__main__':
    main()
__main__ __name__ импорт скрипт

Что такое pdb?

Встроенный отладчик: pdb.set_trace() стартует интерактивную сессию.

import pdb; pdb.set_trace()
pdb отладка set_trace debug

Как использовать type guard?

typing.TypeGuard позволяет предикатами уточнять типы для статанализа.

def is_int(x) -> TypeGuard[int]: return isinstance(x, int)
TypeGuard typing предикат тип

Что такое singledispatch?

functools.singledispatch реализует диспетчеризацию по типу первого аргумента.

from functools import singledispatch
@singledispatch
def f(x): ...
@f.register(int)
def _(x): ...
singledispatch functools generic тип

Как сделать кэш в памяти быстро?

Для функций — lru_cache; для объектов — dict + инвалидация.

from functools import lru_cache
@lru_cache
def calc(x): ...
кэш lru_cache мемоизация словарь

Как парсить аргументы командной строки кратко?

argparse или click/typer для лаконичного синтаксиса и автодоки.

import click
@click.command()
@click.option('--x')
def main(x): ...
argparse click typer CLI

Что такое __getattr__ и __getattribute__?

__getattribute__ вызывается всегда; __getattr__ — только если атрибут не найден.

class C:
    def __getattribute__(self, name): ...
    def __getattr__(self, name): ...
__getattr__ __getattribute__ атрибут доступ

Как работает slots с наследованием?

Нужно объявлять __slots__ во всех классах; слоты предков объединяются.

class A: __slots__=('x',)
class B(A): __slots__=('y',)
__slots__ наследование слоты класс

Что такое __enter__ возвращает?

__enter__ может вернуть ресурс, присваиваемый после as.

with open('f') as f: ...  # f из __enter__
__enter__ with as контекст

Как обрабатывать большие файлы построчно?

Итерироваться по файлу или использовать fileinput; не читать целиком.

for line in open('big.txt', 'r'): process(line)
файл построчно итерация fileinput

Что такое zipfile и tarfile?

Модули stdlib для работы с zip/tar: чтение/запись/список содержимого.

import zipfile
with zipfile.ZipFile('a.zip','w') as z: z.write('file.txt')
zipfile tarfile архив stdlib

Как безопасно исполнять внешний код?

Не использовать eval/exec на непроверенных данных; запускать изолированно (subprocess, контейнер).

subprocess.run(['python','script.py'])
eval exec subprocess безопасность

Как работает subprocess.run?

Запускает команду, может ждать завершения и вернуть CompletedProcess; для потоков ввода/вывода использовать pipes.

subprocess.run(['ls','-l'], check=True, capture_output=True)
subprocess run Popen stdout

Что такое importlib?

Модуль для динамического импорта/перезагрузки модулей: import_module, reload.

import importlib
mod = importlib.import_module('math')
importlib импорт dynamic reload

Как предотвратить рекурсивный импорт?

Декуплировать модули, переносить импорты внутрь функций, выделять общее в отдельный модуль.

def func():
    from . import other
    ...
рекурсивный импорт circular refactor модуль

Что такое __future__ импорты?

Включают поведение будущих версий (division, annotations и др.) для совместимости.

from __future__ import annotations
__future__ annotations division совместимость

Как ускорить численные вычисления?

NumPy/Numba/Cython; избегать питонских циклов, использовать векторизацию/JIT.

import numpy as np
np.array([1,2,3]) * 2
NumPy Numba Cython векторизация

Как распараллелить CPU-bound задачи?

multiprocessing или ProcessPoolExecutor, либо C/Numba без GIL.

from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor() as ex: ex.map(f, data)
CPU-bound ProcessPoolExecutor multiprocessing GIL

Как обрабатывать сигналы остановки в asyncio?

add_signal_handler на Unix; на Windows ловить KeyboardInterrupt и ставить Event/flag.

loop.add_signal_handler(signal.SIGINT, cb)  # Unix
asyncio signal KeyboardInterrupt Windows