Основы асинхронности в Python #4: Генераторы и событийный цикл Round Robin

Поделиться
HTML-код
  • Опубликовано: 2 янв 2025

Комментарии • 114

  • @zaemiel
    @zaemiel  6 лет назад +142

    В предыдущих сериях:
    Я знаю, что вы ждете скринкаст про asyncio и async/await.
    Еще разок хочу повториться, что ирония ситуации заключается в том, что эти видео и есть - про модуль asyncio и про синтаксис async/await.
    Вам может показаться идиотизмом то, что я говорю о таких странных вещах, как асинхронность на колбэках или на генераторах (об этом позже) в то время, когда "все пишут" с помощью asyncio и async/await.
    Человек приходит сюда послушать про асинхронность, в надежде, что уж тут-то он сразу поймет, как эти штуки работают - ведь "Python - это очень легкий язык", верно?
    Он ищет волшебную красную таблеточку: "Весь Python за 7 легких уроков", а получает вот эту вот непонятную хрень.
    Разочарование.
    У меня для вас есть новости:
    1. Легкого пути нет.
    2. Волшебной и вкусной красной таблеточки, от которой вы еще и удовольстве получите - тоже нет.
    3. Все очень долго, сложно, неинтересно и непонятно.
    Ключевой момент здесь в том, что те, кто используют asyncio, async/await все, о чем я здесь говорю уже знают, потому что эти темы не свалились на них с неба. Эти люди развивались вместе с концепциями асинхронности. Для них это просто очередной уровень абстракции над тем, что они и так пишут/используют.
    Если к скринкасту про asyncio, async/await вам не будет понятно:
    - как работают событийные циклы
    - как работают генераторы и корутины на их основе
    то и эти темы будут, скорее всего, по-прежнему для вас закрыты.
    Следующее видео будет опубликовано в субботу 15-го декабря.

    • @oleksandrkovtunov487
      @oleksandrkovtunov487 3 года назад

      а что делать если хоть и долго но интересно?)

    • @frankypenkie
      @frankypenkie 2 года назад +2

      Вы лучший из тех, кто это объяснял мне это!

    • @АндрейА-ю3б
      @АндрейА-ю3б Год назад +1

      Блин это что нужно, надеюсь все пробелы закрою теперь.

    • @YGNETATEL_3000
      @YGNETATEL_3000 7 месяцев назад

      7:20 не мили секунд , а микросекунд . Спасибо за внимание и за видос!

    • @MrZeka13
      @MrZeka13 4 месяца назад

      чувак, куча говнокодеров ничего этого не знаю и успешно используют async/await

  • @игорьбелоусов-х3д
    @игорьбелоусов-х3д 5 лет назад +155

    Рад что пока всякие Хайди и Дудари занимаются популизмом и пустословием находятся люди, которые делают реальный контент для реальных задач. спасибо!

    • @zaemiel
      @zaemiel  5 лет назад +6

      Спасибо

    • @moxxiq
      @moxxiq 4 года назад +1

      Солидарен и удивлен, что именно этот плейлист первый в поиске

    • @googleadmin4749
      @googleadmin4749 4 года назад

      @@moxxiq Ваще пушка!

    • @Katar1x
      @Katar1x 2 года назад +5

      И самое главное - на высшем уровне, тут даже универ в сторонке стоит по уровню подачи

  • @АнтонГоленев
    @АнтонГоленев 3 месяца назад +1

    Лучшее объяснение генераторов, которое я видел

  • @ArntorRUS
    @ArntorRUS 2 месяца назад

    Спасибо, это лучшее объяснение генераторов, что встречал!

  • @dasha317317
    @dasha317317 5 месяцев назад

    наконец стало понятно что такое генератор, видела много уроков и статей, но именно этот ролик зашёл

  • @ИванИванов-н9т9ъ
    @ИванИванов-н9т9ъ 5 лет назад +8

    Олег, Вы прекрасно объясняете. Спасибо Вам. С большим удовольствием и интересом смотрю Ваши уроки.

  • @alexeysukhinin8036
    @alexeysukhinin8036 4 года назад +10

    Шикарная подача. Я привык, что по разработке адекватную информацию можно найти только на английском языке. Данный плейлист затмил подачей и уровнем изложения всех англоязычных авторов. Обязательно посмотрю обучение по async/await, когда с эти плейлистом закончу.

  • @ДмитрийМасленников-ф3х

    Семь, 20-45 минутных роликов на ютубе полезней, чем чем 1ый курс программирования в моём институте. Коротко об IT образовании в России.

    • @xximde
      @xximde 7 месяцев назад

      Чем все 4 года обучения

  • @imgnl
    @imgnl 6 лет назад +17

    Спасибо, Олег!

    • @l33tarrgin
      @l33tarrgin 6 лет назад

      Как тесен ютюб. Привет от Чубайса

    • @imgnl
      @imgnl 6 лет назад

      @@l33tarrgin не ютуб тесен, а я популярна :D привет от рандомного ноунейма)

  • @andreyzaytsev1292
    @andreyzaytsev1292 3 года назад +1

    Мне особенно понравилась аналогия с воровством воды из бассейна соседа. Легко усваивается и врезается в память!

  • @GreekkAlex
    @GreekkAlex 6 лет назад +9

    Молчанов, Вы - красавчик!!!

  • @Nfix106
    @Nfix106 2 года назад +3

    Спасибо за видео, как всегда подача 10 из 10. Очень жаль что нет больше новых видео на канале.
    Мало кто может объяснять так темы, обычно натыкаешься на видео где авторы проходятся по верхам а в глубь копать не хотят.
    Будто бояться, что отпугнут подписчиков/зрителей.
    А на просторах русскоязычного ютуба серьёзного контента по пальцам пересчитать.
    Олегу всех благ, и огромное спасибо за ваш труд.

  • @ДаниилСоловьев-э6ш
    @ДаниилСоловьев-э6ш 3 года назад

    Лучшее объяснение генератора, которое я когда-либо слышал)

  • @nonpiramid
    @nonpiramid 3 года назад

    Одно из полезнейших видео, просмотренных мной в жизни

  • @АлексеевА-л8н
    @АлексеевА-л8н 5 лет назад +1

    Чрезвычайно полезные видео, отличная подача материала, всё по полочкам. Удивляет маленькое количество лайков. Огромное спасибо за работу, Олег!

  • @VitalySem
    @VitalySem Год назад

    Про генератори - круто. Реально не знав.

  • @saitaro
    @saitaro 5 лет назад +14

    Молчанова - в президенты!

  • @ЕрвандАгаджанян-в3к
    @ЕрвандАгаджанян-в3к 3 года назад +1

    Огромнейшая благодарность за ваш труд)))!!!!!

  • @igorcherepanov4765
    @igorcherepanov4765 4 года назад

    контент просто огонь, придется весь канал пересматривать

  • @david_shiko
    @david_shiko 4 года назад +2

    4:30 - "Вы не сможете реализовать подобное поведение без генераторов)"
    Вариант 1, с сохранением состояние в глобальной области
    >>> i = 0
    >>> def foo(name):
    global i
    if i < len(name):
    res = name[i]
    i += 1
    return res
    else:
    raise StopIteration>>> i = 0
    >>> foo('oleg')
    'o'
    >>> foo('oleg')
    'l'
    >>> foo('oleg')
    'e'
    >>> foo('oleg')
    'g'
    >>> foo('oleg')
    Traceback (most recent call last):
    File "", line 1, in
    foo('oleg')
    File "", line 8, in foo
    raise StopIteration
    StopIteration
    >>>
    Вариант 2, с сохранением состояния в имени ф-и (кстати, быстрый гуглинг относительно того, где генераторы хранят свои состояния ничего не дал, но думаю, тоже где то в атрибутах)
    >>> def m_0(name):
    i = int(globals()[inspect.currentframe().f_code.co_name].__name__[-1])
    if i < len(name):
    print(name[i])
    i += 1
    new_func_name = inspect.currentframe().f_code.co_name[-1] + str(i)
    globals()[inspect.currentframe().f_code.co_name].__name__ = new_func_name
    else:
    raise StopIteration

    >>> m_0('oleg')
    o
    >>> m_0('oleg')
    l
    >>> m_0('oleg')
    e
    >>> m_0('oleg')
    g
    >>> m_0('oleg')
    Traceback (most recent call last):
    File "", line 1, in
    m_0('oleg')
    File "", line 9, in m_0
    raise StopIteration
    StopIteration
    >>>
    Но автор прав, все это велосипеды, генераторы удобнее и хранят состояние изолированно, а не во внешней области.

    • @grehban
      @grehban 4 года назад

      Глобальные переменные это не очень хорошо...

  • @KikrAzz
    @KikrAzz Год назад

    WOW! Прекрасный материал!

  • @vladimirpa177
    @vladimirpa177 3 года назад +1

    Спасибо за Ваш труд, очень полезные уроки.

  • @ДмитрийМакаров-я7м
    @ДмитрийМакаров-я7м 4 года назад

    Чувак, ты гениально просто все объясняешь!

  • @artur.tokranov
    @artur.tokranov Год назад

    Топовые уроки, спасибо большое!

  • @a98cb985
    @a98cb985 4 года назад +1

    Спасибо, наконец-то понял yield. Вроде простой принцип работы, но тупил на нем

  • @mikhailsokolenko9797
    @mikhailsokolenko9797 Год назад

    Классная подача, спасибо!
    Здорово, что на простых примерах показываете сам принцип. Самое сложное по данной теме - научиться "думать асинхронно". Перестроиться с синхронного проектирования на асинхронное.
    Небольшое замечание: в ф-ции gen_filename для названия переменной используется имя встроенной функции (sum), что является не самой хорошей практикой. Вы, я думаю в курсе пагубности подобной практики, это скорее информация для новичков. Лучше выбирать другие названия переменных. В вашем примере это не страшно, т.к. переменная определяется только в локальной области видимости.
    Ну а в целом, такие действия могут привести к подобным результатам:
    >>> sum([1, 2, 3, 4])
    10
    >>> sum = 234 + 234
    >>> sum([1, 2, 3, 4])
    Traceback (most recent call last):
    File "", line 1, in
    TypeError: 'int' object is not callable

  • @andredru4278
    @andredru4278 Год назад

    Спасибо. Очень понравилось видео.

  • @phil4765
    @phil4765 5 лет назад +1

    Спасибо за проделанную работу, автору респект

  • @Das.Kleine.Krokodil
    @Das.Kleine.Krokodil 3 года назад +2

    00:00 Генераторы. Yield
    13:32 Событийный цикл Round Robin

  • @НиколайКочкин-в8с

    Видео огонь!🔥

  • @happypanda1995
    @happypanda1995 6 лет назад +31

    А про GIL thread и multiprocessing снимать собираетесь? =)

    • @zaemiel
      @zaemiel  6 лет назад +3

      не знаю пока. Пока даже это никого особо не интересует.

    • @happypanda1995
      @happypanda1995 6 лет назад +6

      @@zaemiel ну значит я первый заинтересованный :D

    • @viktor3512
      @viktor3512 4 года назад +6

      Не один )

    • @АртемРудницкий-к9щ
      @АртемРудницкий-к9щ 4 года назад +4

      снимите пожайлуйста)

    • @ГенадійКостенко
      @ГенадійКостенко 4 года назад +8

      Буду рад увидеть видео про GIL, thread и multiprocessing.

  • @caiman101
    @caiman101 3 года назад

    Очень помогаешь разобраться, спасибо тебе!

  • @bekaryukovmv
    @bekaryukovmv 5 лет назад

    Всё чётко и по делу. Работа генераторов стала намного понятнее!

  • @alexeyalex4271
    @alexeyalex4271 3 года назад

    Добрый день Олег, хочу прежде всего сказать спасибо за ваши уроки, отличный материал и проделанную работу. В этом видео вы говорите, что реализовать поведение генератора с помощью обычных функций не получится, но я попробовал и вот такая история вполне себе работает, даже метод .next() получилось реализовать (из за того что ключ не может начинаться с '_' не получилось реализовать .__next__() но выглядит как в python 2.x)
    def get_f_generator(end, start=0, step=1):
    """
    docstring
    """
    r = start
    def next():
    """
    docstring
    """
    nonlocal r
    if r == start:
    f = r
    r += step
    return f
    if end and r >= end:
    raise StopIteration
    else:
    f = r
    r += step
    return f
    FunctionBaseGenerator = namedtuple('FunctionBaseGenerator', ['next'])
    f_generator = FunctionBaseGenerator(next)
    return f_generator
    if __name__ == "__main__":
    f_generator = get_f_generator(10,step=2) # call f_generator.next() for generate

  • @zip1982besh
    @zip1982besh 5 лет назад +1

    чувак ты сделал доброе дело )))) ... Спасибо!!! В ОСРВ FreeRTOS тоже похожая функциональность. Есть Планировщик задач (sheduler) он на мой взгляд event_loop (uvloop). И разные стратегии многозадачности (кооперативная , вытесняющая, гибридная итд). Также там возможно применять сопрограммы. Они по функциональности ближе к данной теме.

  • @babymayby9270
    @babymayby9270 4 года назад +1

    наконец то я понял yield )

  • @yaarobmohammad1020
    @yaarobmohammad1020 2 года назад

    Thanks a lot

  • @ИванИванов-д1ф7ж
    @ИванИванов-д1ф7ж 4 года назад

    Все просто супер! Но я задался целью написать без помощи yield похожее поведение, и все прекрассно получилось. Но затем я переписал в виде класса чтобы было симпотичнее)
    class Gen():
    def __init__(self, sequence):
    self.sequence = sequence
    self.sequence_len = len(sequence)
    self.counter = 0
    def next_symbol(self):
    if self.counter == self.sequence_len:
    self.counter = 0
    raise StopIteration
    result = self.sequence[self.counter]
    self.counter += 1
    return result
    Скажите, пожалуйста если я ошибаюсь, но вроде поведение тоже самое.

  • @golotus
    @golotus 6 лет назад

    После просмотра осталась одна не очевидная вещь о которой хотел бы спросить. Она звучит так:
    18:24 - Почему yield одного генератора выбрасывал последовательность букв: o l e g,
    в то время как второй, оставлял за собой неизменную последовательность: 4 4 4 4.
    Когда вы написали два генератора и вставили их в "вечный цикл", я ожидал увидеть результат o4 l3 e2 g1.
    Прошу прощение за ранее, если что-то упустил или если в вопросе есть ответ. Пока не экспериментировал самостоятельно. Но думаю в процессе отвечу себе сам на этот вопрос.
    Большое спасибо за ваши труды. Очень полезно и информативно! Ждем следующую серию.

    • @zaemiel
      @zaemiel  6 лет назад

      Я об этом сказал там - я ошибся и стал отдавать (yield) n вместо i. Опечатка.

  • @catexis1
    @catexis1 6 лет назад +1

    Спасибо!

  • @grehban
    @grehban 4 года назад +1

    4:20 ну почему же
    def cashe(data):
    def wrapper(*args, **kwargs):
    nonlocal data
    if len(data) == 0:
    raise StopIteration
    for i in data:
    data = data[1:]
    return i
    return wrapper
    a = cashe("oleg")
    print(a())
    print(a())
    print(a())
    print(a())
    >>>
    o
    l
    e
    g
    Обычное замыкание

    • @IlyaIlya_lopkop
      @IlyaIlya_lopkop 3 года назад

      Круто, но если бы ещё код был питонячий, то было бы ещё круче)

    • @grehban
      @grehban 3 года назад

      @@IlyaIlya_lopkop код питонячий:)

    • @grehban
      @grehban 3 года назад

      @@IlyaIlya_lopkop но я бы сказал что юзать это не стоит) комменту почти год

  • @maksimaksi
    @maksimaksi 5 лет назад +1

    Олег, спасибо!
    желательно только сделать чуть ярче и крупнее

  • @AlexK544
    @AlexK544 6 лет назад +1

    Не устану говорить спасибо.
    Подробностей и тонкостей много не бывает. Очень качественно подан материал. Олег, будут в будущем серии с разъяснением когда какие библиотеки для асинхронного выполнения кода применять?
    В чем разница между asyncio, threading и multiprocessing?
    Сейчас уже многое стало понятней, но дьявол как всегда кроется в мелочах :)

    • @zaemiel
      @zaemiel  6 лет назад +7

      Ну... В первом видео про это было.
      Асинхронность - про выполнение задач в одном потоке.
      Threading - для выполнения задач в разных потоках, но в одном процессе. Задачи должны быть I/O-bound
      Multiprocessing - про выполнение задач в разных процессах, чтобы можно было использовать на полную катушку наши многоядерные архитектуры компов. Это для CPU-bound задач (расчеты, вычисления и проч.)
      В одном процессе может быть несколько потоков (речь идет о потоке выполнения программы). И этот процесс выполняется только одним ядром CPU. Т.е. нет смысла в том, чтобы задачу по каким-либо расчетам распараллеливать среди нескольких потоков (Threads), поскольку они все завязаны на одном ядре CPU.
      Расчеты и вычисления (CPU-bound) распараллеливают по нескольким процессам - т.е. используется multiprocessing.

    • @AlexK544
      @AlexK544 6 лет назад

      Спасибо за ответ.
      Сложная тема, заходит с сильным трением.
      Думаю тут дело в моем непонимании основ, которые как раз и разжевываются.

    • @zaemiel
      @zaemiel  6 лет назад +5

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

    • @golotus
      @golotus 6 лет назад

      @@zaemiel Изумительный материал, а ваши комментарии, как прекрасный штрих мастера.

  • @johnysh6480
    @johnysh6480 Год назад

    Отъелдил N) Смех в храме тишины)

  • @9keepa
    @9keepa 5 лет назад

    7:26 вроде метод формат сам приводит типы инт к стрингу.. по крайне мере у меня всегда работает с методом format без приведения к типу int

    • @zaemiel
      @zaemiel  5 лет назад

      да, уже отвечал на это как-то. По-моему даже под этим видео.

  • @sainco3036
    @sainco3036 6 лет назад

    Спасибо

  • @АзатМингалеев-в1к
    @АзатМингалеев-в1к 3 года назад

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

  • @ilyasjumadurdyew8074
    @ilyasjumadurdyew8074 4 года назад

    Добрый день. У меня один вопрос. Почему заместо генератора не использовать UUID4? (Именно для генерации уникальных имен)

  • @benyomin94
    @benyomin94 6 лет назад

    Спасибо за серию!
    Олег, два небольших вопроса:
    1) зачем конвертировать в str число, если оно уже подставляется в метод format()?
    2) чем f-string хуже format()? Вроде писать проще, но вы не используете

    • @zaemiel
      @zaemiel  6 лет назад +3

      1. Незачем специально приводить int в string, просто меня иногда клинит во время записи.
      2. f-string не хуже, он даже быстрее, чем format(). Для небольшого количества аргументов я использую format(), потому что это явное использование метода. А еще у меня просто привычка, но я с ней борюсь.

    • @benyomin94
      @benyomin94 6 лет назад

      @@zaemiel спасибо за ответы

    • @keepsilence6843
      @keepsilence6843 5 лет назад

      @@zaemiel Олег, а почему быстрее? Или в смысле не выполнения, а записи?

  • @kozlovsky5692
    @kozlovsky5692 6 лет назад

    Класс

  • @nordost8
    @nordost8 5 лет назад

    Здравствуйте, не могли бы вы рассмотреть в одном из видео или подсказать, как можно реализовать асинхронность на примере чат-бота? Было бы очееееень здорово. Как можно сделать, чтобы эта часть кода (оставлю ссылку), принимающая сообщения и формирующая ответ работала асинхронно и пользователю не приходилось ждать, пока предыдущий пользователь получит ответ? hello-site.ru/share/sinhronnyj-bot/

  • @yobuddy4444
    @yobuddy4444 6 лет назад

    Большое спасибо за уроки! А не подскажите какие у вас настройки nvidia-settings, если таковой используете. Как не пробовал выкручивать: яркость, контрастность и прочие вещи, картинка все равно глаза режет.

    • @zaemiel
      @zaemiel  6 лет назад

      Я что-то не увидел в "NVIDIA X Server Settings" настроек яркости. И как-то не припомню, что что-то специально там подкручивал, т.е. все по дефолту.

  • @dmitryk9440
    @dmitryk9440 4 года назад

    Вы случайно не в области ЦОС работаете? Понятие перемежение редко люди не связанные со связью применяют)

  • @invincible253
    @invincible253 Год назад

    А почему генераторы - только функции? А генераторы-выражения? Например, (i for i in arr)

    • @zaemiel
      @zaemiel  Год назад

      потому что это не генераторы как таковые, а comprehensions.

    • @invincible253
      @invincible253 Год назад

      @@zaemiel всм? Компрехеншн это ж просто способ создания итерируемого объекта, а так g = (i for i in arr) это generator_object

    • @invincible253
      @invincible253 Год назад

      @@zaemiel при чем когда его выводишь так и пишет: generator object (expression)

  • @MRaynold
    @MRaynold Год назад

    🙂

  • @rayder6167
    @rayder6167 4 года назад

    Если поставить get запрос после yield то он не выполнится

    • @acerswift4386
      @acerswift4386 3 года назад

      почему?

    • @rayder6167
      @rayder6167 3 года назад

      @@acerswift4386а сам не знаю , отвечал год назад

  • @homus32
    @homus32 4 года назад +1

    Другая реализация
    return "file-{}.jpeg".format(str(time*300))

  • @kandreyk9159
    @kandreyk9159 4 года назад

    а чем объект, возвращаемый генераторной функцией, отличается от объекта пользовательского класса, реализующего __next__ и __iter__ ?

    • @maxzhenzhera
      @maxzhenzhera 4 года назад

      Класс с данными методами( __iter__ , __next__) реализует паттерн Итератор. Мне кажется то, что ты имел ввиду, выглядит просто как та же генераторная функция в методе __iter__ данного класса, и в таком случае разница будет в том, что генераторная функция вернет тебе генератор, а класс экземпляр, в котором будет реализован данный генератор . Метод __next__ там уже не нужен. Простыми словами - это уже другая реализация.

  • @ivanonin5422
    @ivanonin5422 3 года назад

    Олееееееееег, где видосы, куда пропал? Вернись, ты крут!

    • @IgaMan
      @IgaMan 3 года назад

      Red Eyed Coder Club - новый канал, он теперь только на английском снимает, русскоязычная аудитория посливала его курсы с патреона на торренты и он, видимо, решил больше не делать на русском и похоже теперь только на GO пишет...

    • @АлексейДроздов-л8р
      @АлексейДроздов-л8р 2 года назад

      @@IgaMan спасибо за подсказку, буду мониторить теперь и указанный этот канал!

  • @be1m0nt
    @be1m0nt 6 лет назад

    Шикарный канал, и курс по парсингу, я только начал изучать потому возник вопрос, может кто подскажет из знающих? в платном курсе - парся сайт coinmarketcap, названия парсили по тегу a, есть ли вообще возможность забрать название по тегу из td ? class="no-wrap currency-name" data-sort= существует ли простой способ ?

    • @zaemiel
      @zaemiel  6 лет назад

      Что-то вопрос вообще не понял.
      Фишка в том, как зацепиться за нужный тег. Если таблиц на странице несколько, то просто извлекать текст из td - не прокатит.

    • @be1m0nt
      @be1m0nt 6 лет назад

      @@zaemiel вчера начал смотреть курс, очень понравилось как ты записываешь видео, но еще не успел въехать в тонкости, просто увидел как красную тряпку:
      td class="no-wrap currency-name" data-sort="Bitcoin"
      td class="no-wrap currency-name" data-sort="XRP"
      названия в теге td и попробовал выдрать из него, пыжился разными способами, но отдельно название от туда выдрать не удалось

  • @mikelir1889
    @mikelir1889 2 года назад

    комментарий для продвижения

  • @alexanderpadalka5708
    @alexanderpadalka5708 3 года назад

  • @victorzedwings
    @victorzedwings 3 года назад

    колеми трэшэвых фразеологизмов можно снизить на 400%

  • @chinyass
    @chinyass 4 года назад

    ну сосед из тебя такой себе

  • @andreipopov2700
    @andreipopov2700 5 лет назад

    +1

  • @_ArPTech_
    @_ArPTech_ 4 года назад

    хотел подписаться , но пример с воровством у соседа...

  • @kozlovsky5692
    @kozlovsky5692 6 лет назад

    Класс