Обновить
6
Филя@FeelUs

Пользователь

2
Подписчики
Отправить сообщение

часть 1

  • 1 Что такое асинхронное программирование

  • 2 Что такое asyncio

часть 2

  • 3 Когда стоит использовать модуль asyncio

  • 4 Корутины в Python

часть 3

  • 5 Определение, создание и запуск корутин

		asyncio.run(main())
  • 6 Цикл событий asyncio

		asyncio.new_event_loop()
		asyncio.get_running_loop()
  • 7 Создание и запуск asyncio-задач

		asyncio.create_task(coro)
		asyncio.ensure_future(task_coroutine())
		asyncio.get_event_loop()
		loop.create_task(task_coroutine())

часть 4

  • 8 Работа с задачами и получение сведений о них

		task.done()
		task.cancelled()
		task.result()
		asyncio.CancelledError
		asyncio.InvalidStateError
		task.exception()
		task.cancel()
		task.add_done_callback(handle)
		task.remove_done_callback(handle)
		task.set_name('MyTask')
		task.get_name()
  • 9 Текущие и выполняющиеся задачи

		asyncio.current_task()
		asyncio.all_tasks()
		asyncio.sleep(1)
		task.get_coro()

часть 5

  • 10 Конкурентный запуск нескольких корутин

		asyncio.gather()
  • 11 Ожидание выполнения некоего условия для коллекции задач

		asyncio.wait()
  • 12 Ожидание выполнения корутины с указанием лимита времени

		asyncio.wait_for()
		asyncio.TimeoutError
  • 13 Защита задач от отмены их выполнения

		asyncio.shield()
		shield.cancel()

часть 6

  • 14 Запуск блокирующих задач в asyncio-программах

		asyncio.to_thread() -> ThreadPoolExecutor
		loop.run_in_executor()
  • 15 Асинхронные итераторы

		async for
		__aiter__(self):
		__anext__(self):
  • 16 Асинхронные генераторы

часть 7

  • 17 Асинхронные менеджеры контекста

		__aenter__()
		__aexit__()
		async with
  • 18 Асинхронные comprehension-выражения

		[a async for a in agenerator]
		[await a for a in awaitables]
  • 19 Выполнение команд в неблокирующих подпроцессах

		asyncio.create_subprocess_exec()
		asyncio.create_subprocess_shell()
		process.terminate()
		process.communicate()
		await process.stdout.readline()

часть 8

  • 20 Неблокирующие потоки

		asyncio.open_connection()
		asyncio.start_server()
		asyncio.StreamWriter
		writer.write(byte_data)
		writer.drain()
		reader.read()
		reader.readline()
		writer.close()
		writer.wait_closed()
		writer.is_closing()
  • 21 Пример проверки состояния веб-сайта

  • 22 Распространённые ошибки, которые допускают разработчики при работе с asyncio

часть 9

  • 23 Часто задаваемые вопросы об asyncio

  • 24 Распространённые возражения против использования asyncio

  • 25 Дополнительные материалы

  • 26 Итоги

а, ну да, в разделе “uncancel и вложенные таймауты” про это уже сказано

насколько применим такой подход?

me = asyncio.current_task()
try:
	...
except asyncio.CancelledError:
	...
	# задача решила, что всё-таки не должна отменяться
	me.uncancel() # уменьшаем счётчик отмен
	if me.cancelling() > 0: # если остались другие причины отмены
		raise # CancelledError продолжает лететь

сложная статья. А можете сказать, я правильно обрабатываю CancelledError? я CancelledError отдаю в exit_stack.__aexit__, он её обрабатывает и кидает уже осмысленную ошибку

import asyncio
from aioconsole import ainput

from contextlib import AsyncExitStack
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

MCP_SERVER_URL = "http://localhost:3001/mcp"

async def open_connection(exit_stack: AsyncExitStack):
	try:
		read_stream, write_stream, _ = await exit_stack.enter_async_context(
			streamablehttp_client(MCP_SERVER_URL)
		)
		session = await exit_stack.enter_async_context(
			ClientSession(read_stream, write_stream)
		)
		await session.initialize()
		return session
	except BaseException as exc:
		exc = await emergency_close_connection(exit_stack, exc)
		print(f"Не удалось подключиться к {MCP_SERVER_URL}: {exc!r}")
		return None

async def emergency_close_connection(exit_stack: AsyncExitStack, exc: BaseException) -> BaseException:
	# Отдаём исключение в exit_stack.__aexit__, а не просто зовём aclose() -
	# иначе task group внутри streamablehttp_client не поймёт, что отмена уже
	# обработана, и поднимет исходную ошибку ещё раз при закрытии.
	try:
		await exit_stack.__aexit__(type(exc), exc, exc.__traceback__)
	except BaseException as cleanup_exc:
		exc = cleanup_exc
	if isinstance(exc, BaseExceptionGroup):
		return exc.exceptions[0]
	else:
		raise exc

async def close_connection(exit_stack: AsyncExitStack):
	await exit_stack.aclose()


async def main():
	exit_stack = AsyncExitStack()

	session = await open_connection(exit_stack)

	while True:
		user_input = input('\nВы: ')
		if user_input == 'exit':
			break
		if session is not None:
			try:
				tools = await session.list_tools()
				for tool in tools.tools:
					print(tool.name)
			except BaseException as exc:
				exc = await emergency_close_connection(exit_stack, exc)
				print(f"server disconnected {MCP_SERVER_URL}: {exc!r}")
				session = None

	await close_connection(exit_stack)


asyncio.run(main())

например когда плагин git не может закоммитить большой файл, он просто говорит об этом => открываешь termux и за пару команд всё поправляешь.

когда fit чего-то не может - он просто ломается и приходится перенастраивать весь obsidian заново

Я устал от этого дурацкого плагина Fit, в котором постоянно ошибки, и выяснил, что на телефоне можно использовать непосредственно плагин Git. На телефоне он использует isomorphic-git (урезанную реализацию git на js), которая может делать push/pull/commit. А инициализацию репозитория на телефоне надо сделать 1 раз через Termux.

Для параноиков: плагины obsidian могут исполнять произвольный код на компе, а т.к. сейчас модно создавать ssh-ключ, закидывать его на гитхаб и делать git push без пароля, то создать "продвинутый" токен недостаточно. Чтобы защитить гитхаб от обсидиана можно например сделать ssh-ключ с паролем. (И при каждом git push вводить пароль, который будет расшифровывать закрытый ключ для дальнейшего его использования).

вот одна из причин этой ошибки: в репозитории присутствуют файлы, содержащие ?*: или совпадающие с каким-нибудь расширением типа .md. Оказывается такие файлы нельзя создавать в файловой системе андроида. Выяснил после того как попытался склонировать репозиторий через termux.

а как сделать то же самое, что и ipywidgets, только при помощи html/javascript, чтобы в дальнейшем это можно было оформить как отдельную веб-морду без юпитер-ноутбука (но сначала чтобы она была в юпитер-ноутбуке)? Ну HTML/javasctipt можно отобразить при помощи display(HTML(...)), и наверно еще понадобится запустить маленький веб-сервер, чтобы он принимал сигналы из HTML и менял питонские переменные, и как-то всё это подружить...

Компилируем, запускаем

#include <syslog.h>
int main() {
        syslog(LOG_USER | LOG_EMERG,"hello_syslog_emergency");
        syslog(LOG_USER | LOG_ALERT,"hello_syslog_alerts");
        syslog(LOG_USER | LOG_CRIT,"hello_syslog_critical");
        syslog(LOG_USER | LOG_ERR,"hello_syslog_errors");
        syslog(LOG_USER | LOG_WARNING,"hello_syslog_warning");
        syslog(LOG_USER | LOG_NOTICE,"hello_syslog_notice");
        syslog(LOG_USER | LOG_INFO,"hello_syslog_info");
        syslog(LOG_USER | LOG_DEBUG,"hello_syslog_debug");
}

запускаем

journald

нажимаем End, любуемся

отличный пример для моделирования: DC-DC преобразователь www.youtube.com/watch?v=yMOFQTCzt2k
Похоже это перевод softwarefoundations.cis.upenn.edu/lf-current/Basics.html
со скриншотами
perl -Mre=debug -e'"aaaaaa"=~/(a+)\1/'

а это случайно не бэктрекинг?

В примере
perl -Mre=debug -e'"aabbaa"=~/(a+)b+\1/'

помоему все же не классический конечный автомат: его вид динамически меняется в зависимости от того, какой путь ты уже прошел.
опечатка: δ’(p0, aaax) = δ(δ’(p0, aaa), a) = δ(p5, a) = p4
надо заменить на δ’(p0, aaax) = δ(δ’(p0, aaa), x) = δ(p5, x) = p4
Мой опыт подсказывает, что если постить что-то очевидное или не меняющее смысл, но улучшающее понятность, то можно и без АИ.
Ничего подобного, в машине Тьюринга огромное количество ячеек памяти, которые можно изменить и вся ее работа состоит из сплошных GOTO.

Следуя логике статьи конечным идеальным ЯП будет unlambda.
Там даже от лямбда-абстракции отказались!
Да что греха таить, даже от переменных/констант!
Все элементы все равно располагаются на турбинах так же как в статье все располагается на дифференциалах.
Скорость — это скорость или расход жидкости, который напрямую конвертируется в скорость турбины.
Потенциал — давление,
Напряжение — сила или разность давлений, которая напрямую конвертируется в силу, с которой турбина взаимодействует с тем, что к ней прикреплено.
А турбину считаем идеальной, без трения и проскальзывания жидкости.
иначе, когда забываешь, что это лажа, начинают возникать вопросы вроде такого

Информация

В рейтинге
5 478-й
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность