Python : 在字典中存储 class 实例函数

Python : storing class instance function in dict

我尝试编写一个 ChatBot 程序,它会以不同的方式响应每个用户。 所以我这样实现:当有新用户时,要求机器人做某事,我的机器人需要向用户询问更多信息并等待响应消息,我的代码将注册一个键为 [=22 的字典=] 和 call_back 函数的值 class 用户喜欢下面的示例代码。

class User:
    api_dict = {}
    def __init__(self, user_id):
        self.user_id = user_id

    def ask_username(self,chat_env):
        chat_env.send_msg(self.user_id,"Please enter your username")
        api_dict[self.user_id] = self.ask_birth_date

    def ask_birth_date(self,message,chat_env)
        chat_env.send_msg(self.user_id,"Mr. {} what is your birth date".format(message))
        # do some thing            
def hook_function(user_id,message,chat_env)
    if is_first_hook(user_id):
        user = User(user_id)
        user.ask_username()
    else:
        User.api_dict[user_id](message,chat_env)

但它没有工作,因为 python 抛出一个错误,它没有收到 ask_birth_date() 中的 chat_env 参数,我认为 self 没有被传递到功能。 那么有什么办法可以让self仍然与ask_birth_date()相连吗?

我认为您必须将 User 的所有实例存储在某处,以便在首次建立连接时能够调用 ask_username。因此,您可以将 api_dict 转换为 state pattern.

Users = {}  # I'm guessing you already have this!

class User:
    def __init__(self, user_id):
        self.user_id = user_id

    def ask_username(self, chat_env):
        chat_env.send_msg(self.user_id, "Please enter your username")
        self.current = self.ask_birth_date

    def ask_next_question(self, message, chat_env)
        self.current(message, chat_env)

    def ask_birth_date(self, message, chat_env)
        chat_env.send_msg(self.user_id, "Mr. {} what is your birth date".format(message))
        self.current = self.record_birth_date  # for example

# There must be code that does this already
def new_connection(user_id, chat_env):
    Users[user_id] = User(user_id)
    Users[user_id].ask_username(chat_env)

# I assume this is called for every message that arrives from a user
def hook_function(user_id, message, chat_env)
    Users[user_id].ask_next_question(message, chat_env)

更新:

您的挂钩函数未正确调用 ask_username()。这就是您收到错误的原因。这就是为什么你应该 post 所有代码 整个堆栈跟踪!

此代码应修复您的调用站点:

def hook_function(user_id, message, chat_env)
    if is_first_hook(user_id):
        user = User(user_id)
        user.ask_username(chat_env)  # add param here!
        # btw the user instance here is thrown away!
    else:
        User.api_dict[user_id](message, chat_env)

如果以上解决了您的问题,则意味着 User class 是不必要的。您可以将 api_dict 作为全局变量,方法可以成为自由函数。

您的代码可以简化为:

api_dict = {}

def ask_username(chat_env, user_id):
    chat_env.send_msg(user_id, "Please enter your username")
    api_dict[user_id] = ask_birth_date

def ask_birth_date(chat_env, user_id, message)
    chat_env.send_msg(user_id, "Mr. {} what is your birth date".format(message))
    # do some thing            

def hook_function(user_id, message, chat_env)
    if is_first_hook(user_id):
        ask_username(chat_env, user_id)
    else:
        api_dict[user_id](chat_env, user_id, message)