asyncio:类型错误:“协程”对象不可下标

fun*_*res 3 python python-asyncio telethon

尝试使我的代码更加异步并出现此错误:

\n

find = (await loop.run_until_complete(a.finddb()[0])) \n TypeError: 'coroutine' 对象不可下标

\n
from telethon import TelegramClient, events, Button, utils, sync\nimport pymongo\nfrom pymongo import TEXT\nimport re\nimport logging\nimport asyncio\n\nclass Search(): # search in mongodb\n    def __init__(self, search): # connect to mongoDB\n        self.search = search\n        self.myclient = pymongo.MongoClient(\n            "mongodb+srv://:@cluster0.ye4cx.mongodb.net/info?retryWrites=true&w=majority&ssl=true&ssl_cert_reqs=CERT_NONE")\n        self.mydb = self.myclient["info"]\n        self.mycol = self.mydb["comics"]\n\n\n    async def searchdb(self): # finds all comics by request\n        self.mycol.create_index([('title', TEXT)], default_language='english')\n        self.find = self.mycol.find({"$text": {"$search": self.search}})\n        if self.find.count() == 0:\n            return 0\n        else:\n            return (self.find)\n\n    async def finddb(self): # search info for 1 comics\n        self.mycol.create_index([('title', TEXT)], default_language='english')\n        self.find = self.mycol.find({"title": self.search})\n        return (self.find)\n\n@bot.on(events.NewMessage(pattern=r'(?<=|).*(?=|)')) # command for find comics info\nasync def find(event):\n    loop = asyncio.get_event_loop()\n    a = Search(event.text.replace("|", ""))\n    find = await loop.run_until_complete(a.finddb()[0])\n    await event.respond(f'**|{find.get("title")}|**\\n\\n**\xd0\xa1\xd1\x82\xd0\xb0\xd1\x82\xd1\x83\xd1\x81 \xd0\xbf\xd0\xb5\xd1\x80\xd0\xb5\xd0\xb2\xd0\xbe\xd0\xb4\xd0\xb0**: {find.get("status")}\\n**\xd0\x98\xd0\xb7\xd0\xb4\xd0\xb0\xd1\x82\xd0\xb5\xd0\xbb\xd1\x8c**: {find.get("publisher")}\\n\\n**\xd0\x96\xd0\xb0\xd0\xbd\xd1\x80**: {find.get("genres")}\\n**\xd0\x9e\xd0\xbf\xd0\xb8\xd1\x81\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xb5**:\\n{find.get("description")}', buttons=[[Button.inline('\xd0\xa1\xd1\x81\xd1\x8b\xd0\xbb\xd0\xba\xd0\xb8 \xd0\xbd\xd0\xb0 \xd1\x81\xd0\xba\xd0\xb0\xd1\x87\xd0\xba\xd1\x83',  b'next')]])\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试使用电机,但遇到同样的问题,但为什么它不起作用?与 pymongo 完美配合

\n

新麻烦find = (await a.finddb())[0] TypeError: 'AsyncIOMotorCursor' 对象不可下标

\n
from telethon import TelegramClient, events, Button, utils, sync\nimport re\nimport logging\nimport motor.motor_asyncio\n\nclass Search(): # search in mongodb\n    def __init__(self, search): # connect to mongoDB\n        self.search = search\n        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")\n        self.mydb = self.myclient["info"]\n        self.mycol = self.mydb["comics"]\n\n\n\n    async def searchdb(self): # finds all comics by request\n        self.find = self.mycol.find({"$text": {"$search": self.search}})\n        print(self.find)\n        if self.find.count() == 0:\n            return 0\n        else:\n            return (self.find)\n\n    async def finddb(self): # search info for 1 comics\n        self.find = self.mycol.find({"title": self.search})\n        return (self.find)\n\n@bot.on(events.NewMessage(pattern=r'(?<=|).*(?=|)')) # command for find comics info\nasync def find(event):\n    a = Search(event.text.replace("|", ""))\n    find = (await a.finddb())[0]\n    print(find)\n    await event.respond(f'**|{find.get("title")}|**\\n\\n**\xd0\xa1\xd1\x82\xd0\xb0\xd1\x82\xd1\x83\xd1\x81 \xd0\xbf\xd0\xb5\xd1\x80\xd0\xb5\xd0\xb2\xd0\xbe\xd0\xb4\xd0\xb0**: {find.get("status")}\\n**\xd0\x98\xd0\xb7\xd0\xb4\xd0\xb0\xd1\x82\xd0\xb5\xd0\xbb\xd1\x8c**: {find.get("publisher")}\\n\\n**\xd0\x96\xd0\xb0\xd0\xbd\xd1\x80**: {find.get("genres")}\\n**\xd0\x9e\xd0\xbf\xd0\xb8\xd1\x81\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xb5**:\\n{find.get("description")}', buttons=[[Button.inline('\xd0\xa1\xd1\x81\xd1\x8b\xd0\xbb\xd0\xba\xd0\xb8 \xd0\xbd\xd0\xb0 \xd1\x81\xd0\xba\xd0\xb0\xd1\x87\xd0\xba\xd1\x83',  b'next')]])\n
Run Code Online (Sandbox Code Playgroud)\n

dir*_*irn 6

首先让我们从一些一般注意事项开始。find被定义为协程。

async def finddb(self):
Run Code Online (Sandbox Code Playgroud)

您需要等待它才能执行它。

db = await self.finddb()
Run Code Online (Sandbox Code Playgroud)

然后您可以对其返回值进行索引。

db[0]
Run Code Online (Sandbox Code Playgroud)

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

(await self.finddb())[0]
Run Code Online (Sandbox Code Playgroud)

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

您可以将代码减少到

find = (await a.finddb())[0]
Run Code Online (Sandbox Code Playgroud)

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

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