异步:TypeError:“协程”对象不可下标

问题描述

尝试使我的代码更具异步性,并获得此错误

查找=(等待loop.run_until_complete(a.finddb()[0])) TypeError:“协程”对象不可下标

from telethon import TelegramClient,events,Button,utils,sync
import pymongo
from pymongo import TEXT
import re
import logging
import asyncio

class Search(): # search in mongodb
    def __init__(self,search): # connect to mongoDB
        self.search = search
        self.myclient = pymongo.MongoClient(
            "mongodb+srv://:@cluster0.ye4cx.mongodb.net/info?retryWrites=true&w=majority&ssl=true&ssl_cert_reqs=CERT_NONE")
        self.mydb = self.myclient["info"]
        self.mycol = self.mydb["comics"]


    async def searchdb(self): # finds all comics by request
        self.mycol.create_index([('title',TEXT)],default_language='english')
        self.find = self.mycol.find({"$text": {"$search": self.search}})
        if self.find.count() == 0:
            return 0
        else:
            return (self.find)

    async def finddb(self): # search info for 1 comics
        self.mycol.create_index([('title',default_language='english')
        self.find = self.mycol.find({"title": self.search})
        return (self.find)

@bot.on(events.NewMessage(pattern=r'(?<=|).*(?=|)')) # command for find comics info
async def find(event):
    loop = asyncio.get_event_loop()
    a = Search(event.text.replace("|",""))
    find = await loop.run_until_complete(a.finddb()[0])
    await event.respond(f'**|{find.get("title")}|**\n\n**Статус перевода**: {find.get("status")}\n**Издатель**: {find.get("publisher")}\n\n**Жанр**: {find.get("genres")}\n**Описание**:\n{find.get("description")}',buttons=[[Button.inline('Ссылки на скачку',b'next')]])

我尝试使用电动机,但是有相同的问题,但是为什么不起作用?使用pymongo可以完美工作

新问题查找=(等待a.finddb())[0] TypeError:“ AsyncIOMotorCursor”对象不可下标

from telethon import TelegramClient,sync
import re
import logging
import motor.motor_asyncio

class Search(): # search in mongodb
    def __init__(self,search): # connect to mongoDB
        self.search = search
        self.myclient = motor.motor_asyncio.AsyncIOMotorClient("mongodb+srv://login:pass@cluster0.ye4cx.mongodb.net/info?retryWrites=true&w=majority&ssl=true&ssl_cert_reqs=CERT_NONE")
        self.mydb = self.myclient["info"]
        self.mycol = self.mydb["comics"]



    async def searchdb(self): # finds all comics by request
        self.find = self.mycol.find({"$text": {"$search": self.search}})
        print(self.find)
        if self.find.count() == 0:
            return 0
        else:
            return (self.find)

    async def finddb(self): # search info for 1 comics
        self.find = self.mycol.find({"title": self.search})
        return (self.find)

@bot.on(events.NewMessage(pattern=r'(?<=|).*(?=|)')) # command for find comics info
async def find(event):
    a = Search(event.text.replace("|",""))
    find = (await a.finddb())[0]
    print(find)
    await event.respond(f'**|{find.get("title")}|**\n\n**Статус перевода**: {find.get("status")}\n**Издатель**: {find.get("publisher")}\n\n**Жанр**: {find.get("genres")}\n**Описание**:\n{find.get("description")}',b'next')]])

解决方法

首先让我们从一些常规说明开始。 find被定义为协程。

async def finddb(self):

您需要等待它才能执行。

db = await self.finddb()

然后可以索引其返回值。

db[0]

如果您想继续在一行中完成所有操作,则需要将其用括号括起来。

(await self.finddb())[0]

现在进入您的实际代码。 find也是协程。您无法在其中一个内部启动事件循环。调用loop.run_until_complete时,您将得到一个RuntimeError,因为循环已经在运行。您也不能等待run_until_complete,因为它不是协程。 (awaitrun_until_complete都是运行协程或任务的方式。前者用于协程内部,后者用于外部协程。)

您可以将代码缩减为

find = (await a.finddb())[0]

如果您只关心返回的第一个文档,也可以使用PyMongo的find_one而不是find来进一步简化它。

最后,PyMongo本身不支持异步。您正在有效地编写同步代码,并增加了事件循环的开销。如果您希望从asyncio中受益,则应该考虑使用Motor