Size: a a a

2021 October 25

а

алексей in SPb Python
Так вдохновил оффлайн, что захотелось выступить
источник

а

алексей in SPb Python
В меру возможностей помогу с организацией
источник

GV

Gleb Van in SPb Python
Привет, Ребят у кого рекламные агентства/кто разработкой Software занимается в USA / UK / Australia / Canada / Europe - отпишитесь . Есть запрос
источник
2021 October 26

M

Matrix Telegram Brid... in SPb Python
источник

NK

ID:0 in SPb Python
Изменено место сбора: Собираемся в OldHam,  наб. реки Мойки 56.
источник

DS

David Shiko in SPb Python
Всем привет, столкнулся с такой архитектурной (скорее всего) проблемой, не знаю как ее решить по нормальному
У меня есть 3 ф-и:
1. Message handler.
2. Decorator который оборачивает Message handler.
3. Callback handler который вызывает Message handler по колбэку (т.е. декоратор по факту).

@Decorator()
def message_handler(update, context):
   pass

def callback_handler(update, context):
   message_handler(update=update, context=context)


def decorator(some_arg = None):
   def inner_decorator(function):
       def wrapper(*args, **kwargs):
               update = args[0]
               update.message.reply_text(text='Foo')
               return function(*args, **kwargs)
       return wrapper
   return inner_decorator

Проблема:
Декоратор ждет список значений (*args), а Callback handler передает ему значения по ключу, это ожидаемо ведет к ошибке.
Конечно, я могу просто передавать аргументы в виде списка, но мы не ищем легких путей.
Мне кажется проблема скорее в архитектуре, нежели том, как я передаю аргументы.
Как бы мне все же передавать их по значению?

Как временное решение я написал несколько if, но сомневаюсь, что это гуд стайл.
P.s. Эти if ищут объект `update.message.reply_text в аргументах. Иногда я передаю целиком update, иногда update.message и т.п.

def decorator(end: bool = False):
   def inner_decorator(function):
       def wrapper(*args, **kwargs):
           if args:
               update_message_reply_text = args[0]
           elif 'update_message' in kwargs:
               update_message_reply_text = kwargs['update_message'].reply_text
           elif 'update_message_reply_text' in kwargs:
               update_message_reply_text = kwargs['update_message_reply_text']
           elif 'reply_text' in kwargs:
               update_message_reply_text = kwargs['reply_text']
           else:
               update_message_reply_text = lambda text: logger.warning('Incorrect "bot_logger" usage,'
                                                                       'Can not notify user about exception!')
           try:
               return function(*args, **kwargs)
           except Exception as e:
               update_message_reply_text(text=f'Неизвестная ошибка. Попробуйте повторить попытку позднее')
               logger.error(e)
               return -1 if end else None
       return wrapper
   return inner_decorator
источник

DA

Dmitry Alimov in SPb Python
привет! погоди, так у тебя должно быть тогда много разных message_handler и callback_handler с разными параметрами?
источник

DS

David Shiko in SPb Python
Точно, немного соврал, есть 4-ая важная ф-я:
compose_message, - вот она вызывается напрямую из callback_handler и message_handler, ей нужен метод из объекта update, что бы отправить сообщение в ответ.
источник

M

Mike in SPb Python
1 - я бы рекомендовал типы прописать для начала, это сфокусирует на деталях ( это мой ихмо)
2 - если говорить про  ооп больше похоже что ты  хочешь Observer сделать, если про fp то наверное стоит frp посмотреть в простом варианте там loan паттерн что по факту и есть твой декоратор
3 - либо явно вызывать что наверное даже лучше.
4 - в питоне можно арги запретить, def f(*, val_1: str, val_2: str,)

В общем от меня помощи как всегда 😂
источник

M

Mike in SPb Python
Но это все не про динамику а однообразие поведения и дифинишены
источник

DA

Dmitry Alimov in SPb Python
не тут арги не запретишь потому что могут быть разные варианты похоже. можно сделать всё через **kwargs (наверное).

я сначала подумал про dispatch (который functools.singledispatch) но кажется тут можно сделать проще
источник

DA

Dmitry Alimov in SPb Python
вообще варианты
kwargs['update_message'].reply_text
kwargs['update_message_reply_text']
это же одно и то же. проще тогда прокидывать сразу
update_message.reply_text либо только update_message

а reply_text хз что там, но тоже похоже на update_message.reply_text
источник

DS

David Shiko in SPb Python
Вообще если говорить подробнее, то структура немного запутананя, не знаю у меня ли или сам фреймворк такой.
Есть объект bot, он взаимодействует с телегой и юзером (но ему обычно нужен юзер_айди).
Юзер_айди приходит в объекте update, он напоминает бота, но имеют урезанный функционал.
Апдейты принимаются на вход обработчиками.
обычно мне хватает объекта update, но изредка приходится использовать и bot.

Как у меня сделано, есть 3 файла:
Объект bot - взаимодествует с телегой, я ему добавил немного полезных методов от себя (декораторы для обработчиков).
Класс User - общается с крудом
Файл flow - содержит обработчики.

Я думаю, мне нужно импортировать бота внутрь класса`User` и там проводить нестандартные процедуры (которые выходят за рамки "команда-реакция".

Получается файл flow (его обработчики) принимает update от клиента, вызывает методы юзера (который имеет доступ к crud), и изредка юзер использует объект bot. Получается, что bot используется и во flow и в user
источник

DS

David Shiko in SPb Python
И моя проблема решается тем, что compose_message (которому нужен update или bot) нужно сделать как метод юзера
источник

DS

David Shiko in SPb Python
Хотя по факту все упирается в то, кто отправит результат клиенту,
обработчик или объект user внутри него (у которого теперь есть объект bot для отправки результата анпрямую).
Хорошим тоном считается декорировать того, кто отправляет результат клиенту (обработчики из flwo),
но если user будет отправлять результат, то и его по факту нужно декорировать. Это как-то странно
Надеюсь понятно распиал.
источник
2021 October 27

:

:) in SPb Python
Всем привет. В python 3.10 выдает ошибку : "no module named '_typeshed'. В начале кода стоит импорт : " from _typeshed import Self". Как решить эту проблему!? (
источник

A

Alexander in SPb Python
Не импортировать из приватного модуля?
источник

A

Alexander in SPb Python
Чем не решение
источник

:

:) in SPb Python
Поясни, пожалуйста!
источник

:

:) in SPb Python
Что значит приватного (?
источник