电视马拉松导致"运行时警告:从未等待过协程'MessageMethods.send_message'"



我正在尝试运行Telethon文档提供的第一个代码片段。但是,在经历了多个问题之后(这里和这里(,我最终得到了这个修改后的版本:

import os
import sys
from telethon.sync import TelegramClient, events
# import nest_asyncio
# nest_asyncio.apply()
session_name = "<session_name>"
api_id = <api_id>
api_hash = "<api_hash>"

os.chdir(sys.path[0])
if f"{session_name}.session" in os.listdir():
os.remove(f"{session_name}.session")
async with TelegramClient(session_name, api_id, api_hash) as client:
client.send_message('me', 'Hello, myself!')
print(client.download_profile_photo('me'))
@client.on(events.NewMessage(pattern='(?i).*Hello'))
async def handler(event):
await event.reply('Hey!')
client.run_until_disconnected()

然而,现在我收到了以下警告:

usr/local/lib/python3.7/site packages/ipykernel_launcher.py:23:RuntimeWarning:coroutine'MessageMethods.send_message'从未被等待RuntimeWarning:启用tracemalloc以获取对象分配回溯/usr/local/lib/python3.7/site packages/ipykernel_launcher.py:24:Runtime警告:从未等待coroutine"DownloadMethods.download_profile_photo"RuntimeWarning:启用tracemalloc以获取对象分配回溯//usr/local/lib/python3.7/site packages/ipykernel_launcher.py:30:RuntimeWarning:coroutine'UpdateMethods_从未等待run_until_disconnectedRuntimeWarning:在Jupyter上运行代码时,启用tracemalloc以获取对象分配回溯

。下面是我的问题:

  • 这些警告消息意味着什么?我应该如何处理它们
  • 如果工作正常,这个代码的预期结果是什么?我应该在Telegram上收到消息吗?因为除了签名代码,我没有收到任何其他消息
  • @client.on...行开头的@符号是什么意思?那条线应该做什么?从这一行开始,我不理解代码。如果你能帮我理解它,我将不胜感激

只需将await添加到client.send_message('me', 'Hello, myself!')即可解决该错误,并在download_profile_photo完成工作后打印,将图像下载到localhost,这可能就是您什么都看不到的原因。你应该彻底阅读电视文档,以及如何正确使用照片下载

所有对客户端的调用都有延迟,应该一直等待,这样代码就不会被阻止。您应该阅读asyncio教程正确的代码是:

async with TelegramClient(session_name, api_id, api_hash) as client:
await client.send_message('me', 'Hello, myself!')
print(await client.download_profile_photo('me'))
@client.on(events.NewMessage(pattern='(?i).*Hello'))
async def handler(event):
await event.reply('Hey!')
#await client.run_until_disconnected()

@是一个decorator,您应该阅读与decorator相关的PEP,但简而言之,它们在您之前执行一个函数。

在这种情况下,@client.on(events.NewMessage表示:

当有一个新事件恰好是一条与指定模式匹配的消息时,使用名为handler的函数进行处理

Jupyter将运行asyncio事件循环,以便您可以在async def之外使用async for / with / await。这与Telethon的.sync魔法相冲突,在使用Jupyter、IPython或类似产品时,应尽量避免这种魔法。

修复您的代码:

from telethon import TelegramClient, events
#            ^ note no .sync
session_name = "<session_name>"
api_id = <api_id>
api_hash = "<api_hash>"
async with TelegramClient(session_name, api_id, api_hash) as client:
await client.send_message('me', 'Hello, myself!')
# ^ note you need to use `await` in Jupyter
# we are avoiding the `.sync` magic so it needs to be done by yourself
print(await client.download_profile_photo('me'))
#     ^ same here, needs await
@client.on(events.NewMessage(pattern='(?i).*Hello'))
async def handler(event):
await event.reply('Hey!')
await client.run_until_disconnected()
# ^ once again needs await

如果你想让代码在任何地方运行(Jupyter,Pythonshell,正常运行(,只需确保在async def:中执行所有操作

import asyncio
from telethon import TelegramClient, events
session_name = "<session_name>"
api_id = <api_id>
api_hash = "<api_hash>"
async def main():
async with TelegramClient(session_name, api_id, api_hash) as client:
await client.send_message('me', 'Hello, myself!')
print(await client.download_profile_photo('me'))
@client.on(events.NewMessage(pattern='(?i).*Hello'))
async def handler(event):
await event.reply('Hey!')
await client.run_until_disconnected()
# Only this line changes, the rest will work anywhere.
# Jupyter
await main()
# Otherwise
asyncio.run(main())

最新更新