LulzLoL231
@LulzLoL231
Python Developer

Почему возникает ошибка «'NoneType' object is not callable»?

Пользователь вводит переменные (query, where) для поиска по локальной базе данных, код ищет ResID в базе с помощью переданных переменных, и выводит пользователю полученную информацию, Так получается, что в базе при поиске могут выпасть не один ResID, и пользователю даётся краткая информация о записи в базе данных, и просит выбрать нужную, и в то время как если при вводе переменных выдаётся 1 ResID, всё проходит идеально, и запись показывается, но если выпадает больше 1 записи, Python признает в функции (func4) "NoneType" object, и выпадает исключение, в чём проблема так и не понял, экспериментальным путём узнал что func4 и в случае если 1 ResID, и если больше одного является - NoneType, но в 1-ом случае он успешно выполняется, а во 2-ом уже нет, в чём проблема так и не пойму, помогите!

Вероятная часть кода с ошибкой:
def func0(message):
    global where
    global resID
    sumresid = func1(query, where)  # Возвращает ВСЕ найденные resID
    if len(sumresid) > 1:
        bot.send_message(message.chat.id, 'Info:')
        bot.send_message(message.chat.id, 'Results: ' + str(len(sumssid)))
        bot.register_next_step_handler(message, IPMO(message, sumresid))  # если найдено больше 1 resID, передаёт список функции IPMO которая показывает все найденные записи, и даёт выбрать нужную пользователю.
    else:
        resID = func2(query, where)  # Если найден был только 1 resID, возвращает resID
        compRes(message)

def IPMO(message, listOfresID):
    sumresid = listOfresID
    num = 0
    while True:
        print('DEBUG: sumResID: ' + str(sumresid))
        if str(sumresid) == '[]':
            print('DEBUG: IF construct (str(sumresid) == "[]") is Called!')
            bot.send_message(message.chat.id, 'Choice profile (enter resID):')
            bot.register_next_step_handler(message, IPMO_Choice)
            break
        print('DEBUG: While is Working!')
        readyResID = sumresid[0]  # Берёт 1 ResID из списка
        resultuple = func3(readyResID)  # Возвращает tuple с данными по ResID
        resid = resultuple[0]
        var1 = resultuple[1]
        var2 = resultuple[2]
        var3 = resultuple[3]
        bot.send_message(message.chat.id, '[ ! ]: Result #' + str(num))
        bot.send_message(message.chat.id, 'ResID: ' + ssid)
        bot.send_message(message.chat.id, 'Var1: ' + var1)
        bot.send_message(message.chat.id, 'Var2: ' + var2)
        bot.send_message(message.chat.id, 'Var3: ' + var3)
        num = num + 1
        sumresid.remove(sumresid[0])

def IPMO_Choice(message):
    print('DEBUG: Called local func: IPMO_Choice')
    global ResID
    ResID = message.text
    debugCheckResID()
    compRes(message)

def debugCheckResID():
    # Придумана чисто для теста
    print('DEBUG: Called local func: debugCheckResID')
    print('DEBUG: Selected ResID: ' + ResID)

def compRes(message):
    print('DEBUG: Called local func: compRes')
    print('DEBUG: Type of func Func5: ' + str(type(mainInfoResult())))  # Результат: DEBUG: Type of func Func4: <class 'NoneType'>
    bot.send_message(message.chat.id, 'ResID found! (' + ResID + ')')
    bot.send_message(message.chat.id, 'Compiling result...')
    Func4()
    bot.send_message(message.chat.id, 'Func4...COMPILED!')


Вот такой Traceback возвращает:
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/telebot/util.py", line 59, in run
    task(*args, **kwargs)
TypeError: 'NoneType' object is not callable"
Traceback (most recent call last):
  File "bot.py", line 1587, in <module>
    bot.polling(none_stop=True, timeout=60)
  File "/usr/local/lib/python3.5/dist-packages/telebot/__init__.py", line 389, in polling
    self.__threaded_polling(none_stop, interval, timeout)
  File "/usr/local/lib/python3.5/dist-packages/telebot/__init__.py", line 413, in __threaded_polling
    self.worker_pool.raise_exceptions()
  File "/usr/local/lib/python3.5/dist-packages/telebot/util.py", line 108, in raise_exceptions
    six.reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2])
  File "/usr/lib/python3/dist-packages/six.py", line 686, in reraise
    raise value
  File "/usr/local/lib/python3.5/dist-packages/telebot/util.py", line 59, in run
    task(*args, **kwargs)
TypeError: 'NoneType' object is not callable
  • Вопрос задан
  • 8769 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Slavon93
Никогда ботов не писал, но попробую направить:
bot.register_next_step_handler(message, IPMO(message, sumresid))

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

Если загляните вот сюда (ссылка на Github бота), то увидите,
# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
    msg = bot.reply_to(message, """\
Hi there, I am Example bot.
What's your name?
""")
    bot.register_next_step_handler(msg, process_name_step)


def process_name_step(message):
    try:
        chat_id = message.chat.id
        name = message.text
        user = User(name)
        user_dict[chat_id] = user
        msg = bot.reply_to(message, 'How old are you?')
        bot.register_next_step_handler(msg, process_age_step)
    except Exception as e:
        bot.reply_to(message, 'oooops')

Тут, во-первых, устанавливается callback строчкой
bot.register_next_step_handler(msg, process_name_step)
а во-вторых сама функция process_name_step принимает в качестве аргумента message, то есть сообщение, которое было прислано боту, а дальше из него уже берется вся информация.

Короче, скорее всего, вам нужно в функции func0, как только поняли, что ID больше одного, отправлять пользователю сообщения с информацией о найденных ID и ждать ответа. Когда ответ придет, сработает callback IMP0 с аргументом message, из которого станет понятно, что именно хочет пользователь, а дальше ваша стандартная обработка ответа.

Ну, и наверное, еще стоит сказать, что лучше было бы, конечно, не спамить кучу сообщений пользователю на каждый ID, а сформировать одно сообщение со всеми найденными ID и отправить пользователю, а дальше уже ждать ответа именно на него, поскольку аргумент message, который идет первым в bot.register_next_step_handler - это, судя по докам, то сообщение, на которое ожидается ответ.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы