索引错误:列表索引超出范围(查询结果中)

1 投票
1 回答
5403 浏览
提问于 2025-04-16 07:24

我在理解如何处理查询结果时遇到了问题。我问了好几次这个问题,但还是不明白。我从之前的代码中复制了一些内容,勉强让它运行起来,但因为我不理解背后的概念,所以只要稍微改动一下代码就会出错。如果你能告诉我你是怎么理解这里发生的事情,并给我解释一下,我会非常感激。谢谢。

class ReceiveEmail(InboundMailHandler):
    def receive(self, message):
        logging.info("Received email from %s" % message.sender)
        plaintext = message.bodies(content_type='text/plain')
        for text in plaintext:
            txtmsg = ""
            txtmsg = text[1].decode()
            logging.info("Body is %s" % txtmsg)
            logging.info("CC email is %s" % ((message.cc).split(",")[1]))            

        query = User.all()           
        query.filter("userEmail =",  ((message.cc).split(",")[1])) 
        results = query.fetch(1)                   

        for result in results:                     
            result.userScore += 1                  

        um = results[0]                            
        um.userScore = result.userScore            
        um.put()

在我理解的这个代码中,查询从抄送列表中取出了第二个邮箱地址,并获取了结果。

然后我把用户的得分增加了1。

接下来,我想在数据存储中更新这个项目,所以我说

        um = results[0]                            
        um.userScore = result.userScore            
        um.put()

但是这给了我一个“索引超出范围”的错误:

um = results[0]
IndexError: list index out of range

为什么会这样?我想象 results[0] 是结果的第一个项目。为什么会超出范围?我能想到的唯一原因是,列表可能是 None。但我不明白为什么。它应该有我获取的那个项目。

而且,如果我通过把索引从 [1] 改成 [0] 来测试第一个邮箱地址

query.filter("userEmail =",  ((message.cc).split(",")[0]))

那么我就不会得到 IndexError

我到底哪里做错了?

谢谢!

编辑

看看评论:

(message.cc).split(",")[0]) 

在邮箱前面留了个空格(从第二个邮箱开始),所以查询没有匹配到它们;

>>> cc.split(",")
['cc12@example.com', ' cc13@example.com', ' cc13@example.com']

在逗号后面加个空格解决了这个问题:

>>> listcc = cc.split(", ")
>>> listcc
['cc12@example.com', 'cc13@example.com', 'cc13@example.com']
>>> 

1 个回答

1

要理解这段代码,可以把它拆开来,一块一块地看:

class ReceiveEmail(InboundMailHandler):
    def receive(self, message):
        logging.info("Received email from %s" % message.sender)

        # Get a list of CC addresses.  This is basically a for loop.
        cc_addresses = [address.strip() for address in message.cc.split(",")]
        # The CC list goes with the message, not the bodies.
        logging.info("CC email is %s" % (cc_addresses))

        # Get and iterate over all of the *plain-text* bodies in the email.
        plaintext = message.bodies(content_type='text/plain')
        for text in plaintext:
            txtmsg = ""
            txtmsg = text[1].decode()
            logging.info("Body is %s" % txtmsg)

        # Setup a query object.
        query = User.all()
        # Filter the user objects to get only the emails in the CC list.
        query.filter("userEmail IN",  cc_addresses)
        # But, only get at most 10 users.
        users = query.fetch(10)

        logging.info('Got %d user entities from the datastore.' % len(users))

        # Iterate over each of the users increasing their score by one.
        for user in users:
            user.userScore += 1

        # Now, write the users back to the datastore.
        db.put(users)
        logging.info('Wrote %d user entities.' % len(users))

我建议你调整一下模型的结构。当你创建用户实体时,可以把关键字设置为电子邮件地址。这样的话,你的查询会变得更高效。

这里有一些参考资料:

撰写回答