admin管理员组

文章数量:1362150

So here's the decorator and the function I use:

#telebot module imported, and another function gets users input and calls the check function with:
    my_bot.register_next_step_handler(message, check)#

def response_checker(func): #this is a decorator for the next function 
    def wrapper(*args):
        if func(*args):     #if the input is correct the decorated function returns an integer, success
            my_bot.register_next_step_handler(args[0], get_course_rating)
        else:               #if the input is incorrect the decorated function returns False
            msg = my_bot.send_message(client_id, 'Error notification')
            my_bot.register_next_step_handler(msg, check) # The question is here. See after code please
    return wrapper

@response_checker
def check(message):                # function checks if users input has the right format
    global course_rating
    try: course_rating = int(message.text)  
    except Exception:
        return False
    if course_rating not in range(0,11):
        return False
    else:                           # if both possible format errors avoided - proceed to the next function
        course_rating = int(message.text)
        get_course_rating()
        my_bot.send_message(client_id, 'Ready to memorize')
        return course_rating

And it works perfectly fine, although I can't understand why. If the initial users input was incorrect, msg.text stores 'Error notification' and this very msg should be passed into the check function. However the bot actually awaits my input and passes that input as a message into the check function instead. Why doesn't it simply pass the msg variable as the message argument?

So here's the decorator and the function I use:

#telebot module imported, and another function gets users input and calls the check function with:
    my_bot.register_next_step_handler(message, check)#

def response_checker(func): #this is a decorator for the next function 
    def wrapper(*args):
        if func(*args):     #if the input is correct the decorated function returns an integer, success
            my_bot.register_next_step_handler(args[0], get_course_rating)
        else:               #if the input is incorrect the decorated function returns False
            msg = my_bot.send_message(client_id, 'Error notification')
            my_bot.register_next_step_handler(msg, check) # The question is here. See after code please
    return wrapper

@response_checker
def check(message):                # function checks if users input has the right format
    global course_rating
    try: course_rating = int(message.text)  
    except Exception:
        return False
    if course_rating not in range(0,11):
        return False
    else:                           # if both possible format errors avoided - proceed to the next function
        course_rating = int(message.text)
        get_course_rating()
        my_bot.send_message(client_id, 'Ready to memorize')
        return course_rating

And it works perfectly fine, although I can't understand why. If the initial users input was incorrect, msg.text stores 'Error notification' and this very msg should be passed into the check function. However the bot actually awaits my input and passes that input as a message into the check function instead. Why doesn't it simply pass the msg variable as the message argument?

Share Improve this question edited Mar 31 at 16:45 user30113406 asked Mar 31 at 16:19 user30113406user30113406 11 bronze badge New contributor user30113406 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 6
  • 1 The wrapper function doesn't have any return statements. What do you expect it to return? – Barmar Commented Mar 31 at 16:31
  • Why do you need course_rating = int(message.text) twice? – Barmar Commented Mar 31 at 16:35
  • Nothing, it just re-asks for input and restarts the check function if the value of message var passed by user is incorrect. What I mean by my question is: does the register_next_step_handler(msg, check) method actually pass its msg argument to the check function or no? – user30113406 Commented Mar 31 at 16:37
  • I thought you meant that the decorator changes the return value of the function. The decorated function always returns None. – Barmar Commented Mar 31 at 16:39
  • first course_rating = int(message.text) checks if the input is integer. second actually converts it to integer to use afterwards – user30113406 Commented Mar 31 at 16:39
 |  Show 1 more comment

1 Answer 1

Reset to default 1

The wrapper needs to save the value returned by func() so it can return it. Your wrapper always returns None.

def response_checker(func): #this is a decorator for the next function 
    def wrapper(*args):
        value = func(*args)
        if not (isinstance(value, bool) and value == False): #if the input is correct the decorated function returns an integer, success
            my_bot.register_next_step_handler(args[0], get_course_rating)
        else:               #if the input is incorrect the decorated function returns False
            msg = my_bot.send_message(client_id, 'Error notification')
            my_bot.register_next_step_handler(msg, check) # The question is here. See after code please
        return value
    return wrapper

You also need to check isinstance(value, bool). Otherwise, if the user enters 0 it will be considered falsey.

本文标签: pythonFunction after decoration changes its result (39return39 value)Stack Overflow