Обновить
81
0.3
Tishka17@Tishka17

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

Отправить сообщение

А подскажите, как будет выглядеть бесконечный список единиц?

Это действительно можно реализовать через рекурсию, а можно реализовать через треды и очереди. А можно заинлайнить и оставить цикл снаружи, а можно... Да миллион вариантов. Человек старательно путает семантику кода и реализацию.

этот код - просто шорткат для

def inner():
   for x in range(10000000):
       yield x
gen = inner()

ещё раз, тут нет рекурсии нигде!!! Ни в одной строке кода не происходит повторного обращения к inner, она вызывается один раз - снаружи. Это не рекурсия! вход в функцию происходит ровно один раз, а вон внутри она уже ставится на паузу.

Вот выше приводились примеры реализации генератора через псевдоцикл и через рекурсию.

Не надо. Приводился пример генератора как отдельной сущности в языке и эмуляция генератора через рекурсию.

Если в языке есть отдельная сущность - внутри может использоваться обычный цикл, но это не обязатно, генератор может например выдавать фиксированное количество данных без цикла, но всё ещё лениво. Пауза в вывполнении не за счет изменения семантики цикла, она появляется за счет семантики yield. Идея в том, что если вам нужен генератор - сделайте генератор.

Собственно, идея почему отказались от goto - людям не нужны произвольные переходы , нужно решать несколько ситуаций и их можно выразить более безопасно и выразительно не теряя в функциональности. Попытка всё выразить через рекурсию так же плоха как попытка всё выразить через цикл.

Это генераторное выражение - альтернативный способ создать генератор. yield нету. цикл фактически есть, но он ленивый.

Она не ложная, если представить что кроме потоков ОС есть логияеские потоки, которые синхронизированы. Просто я не хочу развивать эту терминологию, от нее в данном случае пользы мыло. Я привел этот аналог только потому что он вам будет понятен.

Нет, не надо использовать эти термины. Я мучаюсь тем, чтобы заставить вас использовать знакомые детали реализации и перейти к абстракции. Функция просто ставится на паузу. Всё. Никаких рекурсией, никаких замыканий нет. Есть функция, которую можно ставить на паузу и получать из нее данные по кусочку. А внутри функции такой же цикл как обычно, а может и не цикл.

Возможно такая аналогия будет проще. Представьте что у вас есть отдельный поток, который крутит бесконечный цикл. На каждом вызове yield он останавливается и ждёт пока основной поток съест данные. В реальности никакого потока не создаётся, но логически это очень близко

Тут нет косвенной рекурсии. Функция не запускается заново. Она просто приостанавливается и продолжается с того же места где остановилась. Как это реализовано внутри не важно.

Рекурсия равна вызову функции самой себя. На уровне исходного кода, не на уровне результата компилчции. В приведенном мной примере этого нет ни в каком виде. Это не рекурсия.

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

В любом случае в статье речь именно про стиль написания кода, так то и рекурсия внутри превращается в цикл при оптимизации компилятором, но вы же это как-то игнорируете.

Генераторы - это закономерное расширение синтаксиса циклов, не ломающее стиль кода. В том время как рекурсия - альтернативная форма. Во что оно превращается внутри - да не важно вообще, наверняка там просто goto остаётся после всех возможных компиляций

def gen(): while True: yield 1

for x in gen(): print(x)

У вас gen вызывается внутри gen. У меня - нет. Смотрите:

def gen():
    while True:
         yield 1

for x in gen():
    print(x)

В контексте, это возврат замыкания, которое содержит созадваемый неявно рекурсивный комбинатор, который так же неявно разворачиваетмч в цикл. Но нет, это даже не обязано быть рекурсивным комбинатором, что бы это ни значило, это просто объект у которого есть Стейт и метод next

Нет, не является. В нем нет рекурсивного вызова на уровне языка. Генератор, это просто с внешним контролем перехода к следующему шагу. Смотрите:

while True:
   yield 1

Цикл, рекурсии нет, а генерирует бесконечную последовательность единиц.

А можно чуть подробнее раскрыть тему

  1. Генерации бесконечной последовательности. Как рекурсия может генерировать бесконечную последовательность если у нее есть результат? Кажется дело не в рекурсии как таковой, а в типе результата

  2. Соединения двух циклов. Как вы хотите соединить? Вдоль или поперек? Опять же, если у вас рекурсия, вы получили результат и всё. Так же как функция с циклом вернула результат. Дальше можно вызвать вторую или нет.

Так это не пример while, это for

В коде Litestar было замечено кэширование плутов, что очень сильно влияет на бенчмарки и может совершенно не приносить пользы в реальных приложениях. Попробуйте динамический плуты вида /{id}, какой будет результат?

Что касается FastAPI - Фаст там не про скорость работы, а про скорость разработки, там есть куча мест, которые можно улучшать

На всякий случай дополню, что если используется ORM наоборот нет смысла делать двойное преобразование - пусть модели ORM и используются как сущности бизнес логики. Но это не должно означать что интнрфейс репозитория содержит какую-то информацию об устройстве таблиц и SQL как таковом, это всё ещё скрыто внутри.

Прошу прощения, что плохо выразил мысль. Под упрощением я имео ввиду не писать в сотый раз update или insert или не следить за тем чтобы имена таблиц после as не повторялись при джойнах на одну и ту же. Это не требует квалификации, это требует аккуратности. ORM же наоборот повышает требования к квалификации сотрудника - теперь ему мало знать SQL, надо ещё разбираться в дополнительной технологии.

1
23 ...

Информация

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

Специализация

Бэкенд разработчик, Разработчик мобильных приложений
Ведущий
Python
Docker
Linux
SQL
Git
Golang
Android SDK