Aspiring Data Science
367 subscribers
420 photos
11 videos
10 files
1.86K links
Заметки экономиста о программировании, прогнозировании и принятии решений, научном методе познания.
Контакт: @fingoldo

I call myself a data scientist because I know just enough math, economics & programming to be dangerous.
Download Telegram
#python #codegems

У декоратора @contextmanager есть одно малоизвестное свойство: снабженные им генераторы сами могут использоваться как декораторы. Это возможно, по тому что @contextmanager реализован с помощью класса contextlib.ContextDecorator.

Недооцененное средство языка: часть else может встречаться не только в предложениях if, но также в for, while и try.Правила таковы:
for
Блок else выполняется, только если цикл for дошел до конца (т. е. не было преждевременного выхода с помощью break).
while
Блок else выполняется, только если цикл while завершился вследствие того, что условие приняло ложное значение (а не в результате выхода с помощью break).
try
Блок else выполняется, только если в блоке try не возникало исключение. В официальной документации также сказано: «Исключения, возникшие в части else, не обрабатываются в предшествующих частях except». В любом случае часть else не выполняется и тогда, когда исключение либо одно из предложений, return, break или continue, приводят к передаче управления вовне главного блока составного предложения.

Одной из причин отказа от else в конструкции match ... было отсутствие единого мнения о том, какой должен быть отступ внутри match: следует ли помещать else на том же уровне, что match, или на том же уровне, что case.

Профессор Имре Саймон говаривал, что в науке есть два главных греха: использование разных слов для обозначения одного и того же предмета и использование одного слова для обозначения разных предметов. Имре Саймон (1943–2009) был пионером информатики в Бразилии. Он внес значительный вклад в теорию автоматов и стоял у истоков тропической математики. Он также отстаивал принципы бесплатного программного обеспечения и свободной культуры вообще.

Чтобы помешать потоку Python удерживать GIL бесконечно, интерпретатор байт-кода Python периодически (по умолчанию раз в 5 миллисекунд) приостанавливает текущий поток и тем самым освобождает GIL. Поток может попытаться снова захватить GIL, но если его ждут другие потоки, то планировщик ОС, возможно, выберет один из них.

Функция sys.getswitchinterval() возвращает текущее значение интервала, а функция sys.setswitchinterval(s) изменяет его.

Любая стандартная библиотечная функция Python, делающая системный вызов, освобождает GIL. Сюда относятся все функции, выполняющие дисковый ввод-вывод, сетевой ввод-вывод, а также time.sleep(). Многие счетные функции в библиотеках NumPy/SciPy, а также функции сжатия и распаковки из модулей zlib и bz2 также освобождают GIL.

Свободные от GIL потоки в общем случае не могут изменять объекты Python, но могут читать и записывать память объектов, поддерживающих протокол буфера, например bytearray, array.array и массивы NumPy.

Вызов сопрограммы как coro() сразу же возвращает объект сопрограммы, но не выполняет тело функции coro. Активация тел сопрограмм – задача цикла событий.

Никогда не используйте time.sleep(…) в сопрограммах asyncio, если не хотите приостановить всю программу в целом. Если сопрограмма хочет потратить некоторое время, ничего не делая, она должна вызвать await asyncio.sleep(DELAY). Так она уступит управление циклу событий asyncio, который может дать поработать другим ожидающим сопрограммам.

По определению, сопрограмма может быть отменена только тогда, когда приостановлена в выражении await, и ничто не мешает произвести очистку, обработав исключение CancelledError.

Название Jupyter происходит от Julia, Python и R – первых трех языков, поддержанных системой Notebook.

Если max_workers равно None (по умолчанию), то ThreadPoolExecutor вычисляет значение по формуле (начиная с версии Python 3.8): max_workers = min(32, os.cpu_count() + 4).

Декоратор @asyncio.coroutine для классических и генераторных сопрограмм был объявлен нерекомендуемым в версии 3.8, а в версии Python 3.11 его планируется исключить из языка.

Функция asyncio.get_running_loop была добавлена в версии Python 3.7 для использования внутри сопрограмм. Начиная с версии Python 3.10 asyncio.get_event_loop объявлена нерекомендуемой.
#python #codegems

Ключевое слово for работает с итерируемыми объектами. А ключевое слово await – с объектами, допускающими ожидание.

В настоящее время asyncio не предоставляет асинхронного API файловой системы – в отличие от Node.js.

Начиная с Python 3.9 сопрограмма asyncio.to_thread упрощает делегирование файлового ввода-вывода пулу потоков, предоставляемому библиотекой asyncio.

Под капотом цикл событий asyncio обращается к .send, чтобы привести в действие ваши сопрограммы, а ваши сопрограммы с помощью await вызывают другие сопрограммы, в т. ч. библиотечные. await заимствует большую часть реализации у предложения yield from, которое также обращается к .send для управления сопрограммами.

Цепочка await в конце концов достигает низкоуровневого объекта, допускающего ожидание, который возвращает генератор, к которому цикл событий может обращаться в ответ на такие события, как срабатывание таймера или сетевой ввод-вывод. Низкоуровневые объекты, допускающие ожидание, и генераторы в конце таких цепочек await находятся глубоко внутри библиотек, они не являются частью их API и могут быть расширениями, написанными на C.

Для достижения максимальной производительности при работе с asyncio мы должны заменить все функции, осуществляющие ввод-вывод, асинхронными версиями, которые активируются в результате выполнения await или asyncio.create_task, для того чтобы управление возвращалось циклу событий, пока функция ждет завершения ввода-вывода.

У asyncpg есть важное достоинство – он позволяет обойти отсутствие в PostgreSQL поддержки высокой конкурентности (в этой СУБД используется один серверный процесс на каждое подключение), поскольку реализует пул подключений для внутреннего подключения к самой Postgres.

Эдсгер Дейкстра изобрел семафор в начале 1960-х годов. Идея простая, но настолько гибкая, что большинство других объектов синхронизации, например блокировки и барьеры, можно построить на основе семафоров. В стандартной библиотеке Python есть три класса Semaphore: по одному в модулях threading,multiprocessing и asyncio.

В классе asyncio.Semaphore имеется внутренний счетчик, который уменьшается на 1 всякий раз, как выполняется await для метода-сопрограммы .acquire(), и увеличивается на 1 при вызове метода .release(), который не является сопрограммой, потому что никогда не блокирует выполнение. Начальное значение счетчика задается при создании объекта Semaphore:
semaphore = asyncio.Semaphore(concur_req)

Ожидание .acquire() не приводит к задержке, когда счетчик больше 0, но если счетчик равен 0, то .acquire() приостанавливает ожидающую сопрограмму до тех пор, пока какая-нибудь другая сопрограмма не вызовет .release() для того же семафора, увеличив тем самым счетчик. Вместо того чтобы обращаться к этим методам напрямую, безопаснее использовать semaphore как асинхронный контекстный менеджер:
async with semaphore:
image = await get_flag(client, base_url, cc)


Стоит написать первое async def, как в программе неизбежно будут появляться все новые и новые async def, await,
async with и async for. И внезапно использование неасинхронных библиотек становится проблемой.

Атрибуты-данные и методы в Python носят общее название «атрибуты»; метод – это просто вызываемый атрибут. Помимо атрибутов-данных и методов,мы можем создавать еще свойства, позволяющие заменить открытые атрибуты-данные методами-акцессорами (т. е. методами чтения и установки), не изменяя интерфейс класса.

Пользовательский класс, в котором имеется метод getattr, может реализовать вариант динамических атрибутов, который я называю виртуальными атрибутами; они не объявлены в исходном коде класса и отсутствуют в экземпляре dict, но могут быть получены из какого-то другого места или вычислены «на лету», когда программа пытается прочитать несуществующий атрибут, например obj.no_such_attr.

Функция keyword.iskeyword(…) позволяет проверить, является ли строка ключевым словом языка.