fun*_*res 3 python python-asyncio telethon
尝试使我的代码更加异步并出现此错误:
\nfind = (await loop.run_until_complete(a.finddb()[0])) \n TypeError: 'coroutine' 对象不可下标
\nfrom 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')]])\nRun Code Online (Sandbox Code Playgroud)\n我尝试使用电机,但遇到同样的问题,但为什么它不起作用?与 pymongo 完美配合
\n新麻烦find = (await a.finddb())[0] TypeError: 'AsyncIOMotorCursor' 对象不可下标
\nfrom 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')]])\nRun Code Online (Sandbox Code Playgroud)\n
首先让我们从一些一般注意事项开始。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因为它不是协程。(await和run_until_complete都是运行协程或任务的方法。前者在协程内部使用;后者在协程外部使用。)
您可以将代码减少到
find = (await a.finddb())[0]
Run Code Online (Sandbox Code Playgroud)
您还可以使用 PyMongo 来进一步简化它,find_one而不是find只关心它返回的第一个文档。
最后,PyMongo 本身并不支持 asyncio。您正在有效地编写同步代码,同时增加了事件循环的开销。如果您希望从 asyncio 中受益,您应该考虑使用Motor。