Python:在dict中存储类实例函数

时间:2018-02-04 17:51:39

标签: python python-3.4

我尝试编写一个ChatBot程序,以不同的方式响应每个用户。 所以我这样实现:当有新用户时,请求机器人做某事,我的机器人需要回复用户请求更多信息并等待响应消息,我的代码将使用user_id和值的密钥注册一个dict类User的call_back函数,如下面的示例代码。

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引发了一个错误,它在chat_env中没有收到ask_birth_date()参数,我认为self没有传递给该函数。 那么有没有办法让self依然附加ask_birth_date()

1 个答案:

答案 0 :(得分:0)

我认为您必须将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()。这就是你得到错误的原因。这就是为什么你应该发布所有代码整个堆栈跟踪!

此代码应修复您的呼叫网站:

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类是不必要的。你可以将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)