You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pyTelegramBotAPI开发Telegram Bot时遭遇TypeError错误求助

TypeError: 'NoneType' object is not callable 问题排查(pyTelegramBotAPI)

问题说明

使用pyTelegramBotAPI开发Telegram Bot时,触发TypeError: 'NoneType' object is not callable错误,该错误发生在send_to_club_page()函数发送"hello"之后,尝试改用带lambda的消息处理器也无法解决。

错误根源

问题出在get_search_url函数中的这一行:

bot.register_next_step_handler(message, return_search(message, data))

这里直接调用了return_search(message, data)函数,而不是传入函数对象。由于return_search函数没有显式返回值(默认返回None),register_next_step_handler接收的第二个参数是None。当Bot尝试执行这个下一步处理器时,就会触发"NoneType对象不可调用"的错误。

修复方案

需要将函数调用改为传递函数对象,同时保留所需参数。可以通过两种方式实现:

方式1:使用lambda表达式包装

修改get_search_url中的对应代码:

bot.register_next_step_handler(message, lambda msg: return_search(msg, data))

lambda表达式会创建一个新的函数对象,接收消息参数msg后,再调用return_search并传递正确的参数。

方式2:使用functools.partial(推荐,更清晰)

先导入functools模块,再用partial绑定参数:

import functools

# 在get_search_url函数中
bot.register_next_step_handler(message, functools.partial(return_search, data=data))

partial会生成一个绑定了data参数的新函数,符合register_next_step_handler对函数参数的要求。

修正后的完整代码

import telebot
from telebot import types
from scraper import get_clubs_from_search
import functools  # 新增导入

bot = telebot.TeleBot('###')


@bot.message_handler(commands=['start'])
def start(message):
    msg = f"""Hello, <b>{message.from_user.first_name}</b> \n/help for commands list \n/search for search options"""
    bot.send_message(message.chat.id, msg, parse_mode='html')


@bot.message_handler(commands=['help'])
def help(message):
    msg = f"""You can use the following commands: \n/search to search for a team or a player"""
    bot.send_message(message.chat.id, msg, parse_mode='html')


@bot.message_handler(commands=['search'])
def search(message):
    markup = types.ReplyKeyboardMarkup(row_width=2, resize_keyboard=True)
    player_search = types.KeyboardButton("Search for a player")
    team_search = types.KeyboardButton("Search for a team")
    markup.add(player_search, team_search)
    bot.send_message(message.chat.id, 'Choose an option:', reply_markup=markup)


@bot.message_handler(func=lambda message: message.text in ['Search for a player', 'Search for a team'])
def team_search(message):
    if message.text == 'Search for a team':
        msg = bot.send_message(message.chat.id, "Type the name of the team", reply_markup=types.ForceReply(selective=False))
        bot.register_next_step_handler(msg, get_search_url)


def get_search_url(message):
    """Taking user request and forming a search url. then calling get_clubs_from_search """
    search_request = message.text.split()
    final_query = ""
    for i in range(len(search_request)):
        if i != (len(search_request)-1):
            final_query += f"{search_request[i]}+"
        else:
            final_query += f"{search_request[i]}"
    
    url = f"https://www.transfermarkt.com/schnellsuche/ergebnis/schnellsuche?query={final_query}"
    data = get_clubs_from_search(url)

    # 修复此处:使用lambda包装
    bot.register_next_step_handler(message, lambda msg: return_search(msg, data))
    # 或者用functools.partial:
    # bot.register_next_step_handler(message, functools.partial(return_search, data=data))


def return_search(message, data):
    """Presenting dataframe to user and asking to choose a team"""
    msg = "Please choose the team:\n\n"
    markup = types.ReplyKeyboardMarkup(True)
    for i in range(len(data)):
        msg += f"""{i+1}. {data.loc[i]['club_names']} from {data.loc[i]['country_names']}\n"""
        markup.add(types.KeyboardButton(str(i+1)))  # 注意:转成字符串避免类型问题
    
    final_message = bot.send_message(message.chat.id, msg, reply_markup=markup)
    bot.register_next_step_handler(final_message, send_to_club_page, data)


def send_to_club_page(message, data):
    msg = "hello"
    bot.send_message(message.chat.id, msg, parse_mode='html')


while True:
    bot.polling(none_stop=True, timeout=5)

额外注意:return_search中创建KeyboardButton时,需将整数i+1转为字符串str(i+1),避免潜在类型错误。

额外说明

send_to_club_page函数本身无问题,只要确保它被正确传递给register_next_step_handler即可。之前的错误完全是因为get_search_url中错误地传递了函数执行结果而非函数对象导致的。


内容的提问来源于stack exchange,提问作者Kapytal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 23:31:00