装饰器修饰函数返回值变更及TeleBot注册步骤Handler传参疑问
TeleBot装饰器与步骤处理疑问解答
问题代码与疑问
代码片段
#已导入telebot模块,另有函数获取用户输入并调用check函数: my_bot.register_next_step_handler(message, check) def response_checker(func): #为下一个函数定义的装饰器 def wrapper(*args): if func(*args): #若输入正确,被装饰函数返回整数(成功) my_bot.register_next_step_handler(args[0], get_course_rating) else: #若输入错误,被装饰函数返回False msg = my_bot.send_message(client_id, 'Error notification') my_bot.register_next_step_handler(msg, check) #疑问点在此 return wrapper @response_checker def check(message): #检查用户输入格式是否正确的函数 global course_rating try: course_rating = int(message.text) except Exception: return False if course_rating not in range(0,11): return False else: #若规避两种格式错误,则进入下一个函数 course_rating = int(message.text) get_course_rating() my_bot.send_message(client_id, 'Ready to memorize') return course_rating
疑问点
- 当用户初始输入错误时,
msg.text存储'Error notification',按逻辑该msg应传入check函数,但实际bot会等待新输入并将其作为message传入check函数,为何未直接传入msg变量? - 被装饰后的函数返回值发生了变化,原因是什么?
解答
疑问1:register_next_step_handler的参数作用
register_next_step_handler的设计逻辑是监听指定聊天上下文的下一条用户消息,而非把你传入的消息对象直接作为参数传给回调函数。你传入的msg只是用来告诉TeleBot:要绑定这个消息所属的聊天窗口,等用户在该窗口发送新消息后,再把这条新消息传给check函数。
简言之,这个方法的第一个参数是用来锁定聊天会话的上下文(比如聊天ID、用户ID),不是要传递给回调的内容。所以bot不会把你发送的错误提示消息传给check,而是等待用户的新输入。
疑问2:装饰后函数返回值变化的原因
装饰器response_checker里的wrapper函数没有定义返回值。当你用@response_checker装饰check后,调用check实际上是调用wrapper函数。
原check函数会返回整数(成功时)或False(失败时),但wrapper函数只执行了分支逻辑,没有return任何内容,所以装饰后的check函数调用后返回的是None,这就是返回值变化的原因。如果需要保留原函数的返回值,你需要在wrapper里添加return func(*args)或者根据逻辑返回对应值。
内容的提问来源于stack exchange,提问作者user30113406
相关产品推荐
相关产品推荐

