
Nikolay
13.02.2017
08:12:44
когда питон в рантайме дергает функцию - для этой функции в памяти создается фрейм, в котором уже создаются объекты локальных переменных и всего такого
обычно, когда функция завершает выполнение и возвращает управление через return - фрейм становится ненужен и подбирается GC
но если она возвращает его через yield - фрейм остается в памяти и сохраняет полное текущее состояние функции, чтобы при следующем обращении к объекту этой функции продолжить выполнение с этого законсервированного состояния
это понятно?

Google

Маришка
13.02.2017
08:14:51
Да


Nikolay
13.02.2017
08:16:03
вот, дальше - в питоне корутины реализованы через генераторы, но yield - оператор не только передачи контекста, но и приема значения, то есть можно продолжить выполнение функции, передав ей внутрь что-нибудь еще
именно это позволяет снаружи управлять цепочкой этих корутин, которые передают друг другу значения, явно переключая контекст
это и есть то, что называется кооперативной многозадачностью - когда каждый вычислитель делает свою работу и явно передает контекст дальше
ближе к питону - есть две концепции - корутины и эвентлуп
корутин в питоне сейчас два варианта - классические через генератор и yield и “новые” через async/await, которые по сути то же самое, но в красивой обертке и не совсем обратно совместимые (в 3.6 совместимость почти поправили)
эвентлуп же позволяет связать получение событий от системного вызова с обработкой этого события корутиной, то есть мы висим, скажем, на epoll или на файловом хэндлере, получаем от него события и в лупе в зависимости от вида события дергается разная корутина
получается, что выстраивается дерево - в лупе обработка передается корутине, та, в свою очередь, может дернуть еще несколько корутин (раньше - через yield from, сейчас - через await), и так далее.
поэтому async - это просто оператор, показывающий, что функция является корутиной, а await - оператор ожидания переключения контекста обратно из корутины
фишка в том, что при таком подходе все происходит в одном треде и нам не нужны в явном виде примитивы синхронизации, поскольку контекст переключается явно и параллельного обращения к чему-либо нет в принципе
но поскольку все зависит от лупа - он может переключаться с корутины на корутину, пока какая-то операция висит на await, что позволяет не блокировать все нафиг, а просто не ждать результата честно, пока промис (await) его не вернет, а тупо идти дальше.
это позволяет, в идеальном мире, сделать так, что выполнение программы блокируется только на внешних вызовах, например, непосредственно операции чтения из сокета или файла. То есть стало возможно, скажем, дернуть subprocess и читать его вывод по мере поступления, асинхронно, делая что-то с ним в то же время, а не как во втором питоне
то есть система сама нам присылает событие, когда надо что-то сделать, и наш код - просто коллбэк на это событие

Google

Nikolay
13.02.2017
08:28:30
соответственно, callback hell - это когда колбэков дохрена и они друг друга все дергают и в этом фиг разберешься, но с async/await хоть стало проще понимать, что к чему
вопросы?

Андрей
13.02.2017
08:29:37
Спасибо. Охуенно разложил
сохранил даже

Маришка
13.02.2017
08:31:35
Хм, это то все примерно понятно
Моя проблема в том сейчас что я не могу воспользоваться этими знаниями нормально для решения даже самой простой задачи ._.
Мне нужно будет хорошо поиграться с async/await дабы его понять xd

Nikolay
13.02.2017
08:34:21
ну, работа с корутинами - дело довольно простое. В первую очередь надо создать луп, потом - дерево корутин, которые друг друга ждут через await. И потом вершину дерева через asyncio.ensure_future() запихиваешь в луп и ждешь ее выполнения через loop.run_until_complete()
если у тебя там бесконечный цикл - тогда можно использовать loop.run_forever()

Маришка
13.02.2017
08:34:58
Агась

Nikolay
13.02.2017
08:35:22
если же хочешь несколько корутин и несколько деревьев ждать сразу - тогда пихаешь все корутины в список и на него делаешь asyncio.gather()
тогда управление вернется только когда все корутины в списке закончат работу

Андрей
13.02.2017
08:36:22
она задачу себе придумать не может

Маришка
13.02.2017
08:36:53
> но yield - оператор не только передачи контекста, но и приема значения, то есть можно продолжить выполнение функции, передав ей внутрь что-нибудь еще
А вот с этим чуть поподробнее хоть я и читала про генераторы но я не видела ни разу примера к этомк

Андрей
13.02.2017
08:37:18
значит нужна задача попроще

Nikolay
13.02.2017
08:37:55
у тебя send() отправит внутрь g, который инстанс gen(), значение
причем прямо в середине итерации по нему, то есть выполнения

Маришка
13.02.2017
08:38:43
Постоянно гонять бота по циклу ожидания сообщения от юзверя и чтение rss feed'a и отсылка инфы с него с определенным интервалом

Google

Маришка
13.02.2017
08:39:19
При этом интервал юзверь меняет в любое время

Nikolay
13.02.2017
08:40:16
надо экспериментировать, навскидку не скажу сейчас, как лучше сделать

Маришка
13.02.2017
08:41:38
Мне бы даже самую тупую реализацию сделать дабы оттолкнуться от нее
Я и для моего прошлого бота написала очень хороший говнокод и только потом принялась его оптимизировать

Nikolay
13.02.2017
08:43:43
ну вот глянь на этот код
это ни разу не пример идеального кода, но в целом работает

Маришка
13.02.2017
08:48:39
У меня не лучше
https://github.com/Marina-chan/telegram_useless_bot/tree/master/bot
Сравни первый коммит с текущим
Да и темболее текущий то еще говно ._.

Alexey
13.02.2017
08:53:37

Маришка
13.02.2017
08:53:45
Но в целом работает тоже хддд

Nikolay
13.02.2017
08:54:03

Alexey
13.02.2017
08:54:20

Nikolay
13.02.2017
08:54:36

Alexey
13.02.2017
08:55:07

Jim
13.02.2017
08:57:04

Маришка
13.02.2017
08:57:14
meh

Alexey
13.02.2017
08:58:08

Jim
13.02.2017
08:58:13
УЖОС

Google

Nikolay
13.02.2017
08:58:27
там есть вариант без подписки на весь журнал запросить одну статью, насколько я знаю :)

arisu
13.02.2017
08:58:48

Nikolay
13.02.2017
08:58:50
но это не точно

Alexey
13.02.2017
08:58:56
60р статья
Подписка со скидкой 2200
На год

Nikolay
13.02.2017
08:59:32

Admin
ERROR: S client not available

Nikolay
13.02.2017
08:59:41
они не про async/await, но там примеры хорошие
на классические генераторы

Маришка
13.02.2017
08:59:46
что сложного?
В плане понимания нету ничего сложного, в плане применения новых знаний очень много сложного

arisu
13.02.2017
08:59:55
генератор - всего лишь итератор (объект, у которого определен __iter__)
только записанный в форме функции\

Alexey
13.02.2017
09:00:10
Не не, вы не поняли немного девушку

arisu
13.02.2017
09:00:13
с оператором yield

Alexey
13.02.2017
09:00:38
Объясните ей паттерны применения асинхронщины. Best practices

arisu
13.02.2017
09:01:19
тащемта тут ничего сложного и нет
просто берешь и гуглишь
наверняка по сабжу уже сотни книг исписано
и тысячи вопросов на стеке

Google

Маришка
13.02.2017
09:06:43
Было лучше Николая послушать о котором у меня сложилось очень хорошее мнение еще более хд, а не брать копиппасту с стэка и не понимать зачем это было сделано, хоть и нагуглить можно и это

arisu
13.02.2017
09:07:49
async/adef/await это
реализация красных/синих функций в питоне
на уровне языка

Маришка
13.02.2017
09:09:43
Хз, я бы уверенно пошла на стак с вопросами по плюсам так как их я лучше знаю и учила ~1 год

Alexey
13.02.2017
09:10:25

Александр
13.02.2017
09:10:54

Маришка
13.02.2017
09:10:54
Тако что вопросов "какого хрена это так работает..." в плюсах особо не было

Александр
13.02.2017
09:10:59
иногда лучше молчать)

Маришка
13.02.2017
09:11:26

arisu
13.02.2017
09:12:09
когда спрашивают что-то

Alexey
13.02.2017
09:12:17

Маришка
13.02.2017
09:13:34
meh, видела но не дотрагивалась так как в плюсах хорошо и с тредами работается
Все больше народу с гиктаймс идут сюда

Aldar
13.02.2017
09:18:39
чем вы управляете множеством версий питона? pyenv?

Nikolay
13.02.2017
09:19:27

Aldar
13.02.2017
09:19:42
нет
интересует только 3+