Просмотрев некоторые правила, Прежде чем бота для Telegram отвечает на сообщение


До сих пор я создал пару программ, и вопрос, который появляется-это каким уродливым и немасштабируемыми они выглядят.

Например, в настоящее время я работаю над Telegram-бота. Прежде чем ответить на сообщение, мне нужно проверить, что сообщение следует за пару правил. Для того, чтобы минимизировать количество если/Элиф заявления. Я даже создал пару функций, которые возвращают true или false, если мое условие будет выполнено, но код по-прежнему выглядит очень некрасиво:

# only if messages are not empty and description has a hyphen
if channel and (description and description[0] == '-'):

    if is_channel(channel) and is_length(description):

        if channel_is_size(channel):
            bot.reply_to(message, replies.success_add.format(channel))
            write_results(' '.join(message_words[1:]))
        else:
            bot.reply_to(message, replies.small_chan.format(min_channel_size))

    else:
        bot.reply_to(message, replies.enter_chan)

elif not description and channel:
    bot.reply_to(message, replies.enter_desc_error)
else:
     bot.reply_to(message, replies.enter_addmessage_error) # if empty

Как вы видите, эти условия, при которых сообщение пользователя будет записана в базу данных (это текстовый файл), и это можно увидеть прямо под утроить вложенные операторы if. Я пытался сделать этот код выглядит много приятнее, но сейчас, кажется, очень грязно, и если я хочу добавить дополнительные условия, которые я планирую сделать, этих операторов будет расти из пропорции.



Комментарии
2 ответа

Если вы хотите избавиться от вашего вложенного кода, то вы должны сделать функцию и использовать предохранитель заявления.

Если мы упростим ваш код немного, мы можем иметь:

if C and D and D[0] == '-':
return a # Ignoring other code, for simplicity
elif C and not D:
return b
else:
return c

Вместо этого вы можете иметь:

if C:
if not D:
return b
elif D[0] == '-':
return a
return c

Если вы используете пункт охраны, то вы получаете:

if not C:
return c
if not D:
return b
if D[0] != '-':
return c
return a

Используя ту же логику, можно развернуть все свои ИФС для охраны положения. А остальное оказывается более простым, чем изменить.
Которые могут оставить вас с:

def gen_response(channel, description, replies, message_words):
if not channel:
return replies.enter_addmessage_error

if not description:
return replies.enter_desc_error

if description[0] != '-':
return replies.enter_addmessage_error

if not (is_channel(channel) and is_length(description)):
return replies.enter_chan

if not channel_is_size(channel):
return replies.small_chan.format(min_channel_size)

write_results(' '.join(message_words[1:]))
return replies.success_add.format(channel)

bot.reply_to(message, gen_response(channel, description, replies, message_words))

12
ответ дан 16 февраля 2018 в 09:02 Источник Поделиться

Интересный вопрос. Мы можем решить проблему (хотя бы частично) путем изменения порядка if заявления. Я предполагаю, что вы хотите, чтобы добавить дополнительные условия в первом пункте, что означает, что мы можем 'проваливаться' в начале:

if not description and not channel:
# Empty message
bot.reply_to(message, replies.enter_addmessage_error)

elif not description:
# Non-empty message, empty description
bot.reply_to(message, replies.enter_desc_error)

elif description[0] == "-":
# Non-empty message, non-empty description starting with a hyphen
if is_channel(channel) and is_length(description):
if channel_is_size(channel):
bot.reply_to(message, replies.success_add.format(channel))
write_results(' '.join(message_words[1:]))
else:
# `not channel_is_size(channel)`
bot.reply_to(message, replies.small_chan.format(min_channel_size))
else:
# `not is_channel(channel) and not is_length(description)`
bot.reply_to(message, replies.enter_chan)

Это делает код немного чище и позволяет для других-возвращение положения.

Трудно сказать, что контекст этот кусок кода, но другим решением может быть вызов вспомогательных функций, например

def foo(channel, description):
# No idea what to call this, frankly

def bar():
# idem dito
...
elif description[0] == "-":
foo(channel, description)
...

Это, безусловно, поможет с масштабированием позже.

4
ответ дан 16 февраля 2018 в 09:02 Источник Поделиться