我正在尝试运行Telethon文档提供的this first code snippet。但是,在遇到多个问题(here和here)之后,我最终得到了这个修改后的版本:
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' was never awaited RuntimeWarning: Enable tracemalloc to get the object allocation traceback /usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:24: RuntimeWarning: coroutine 'DownloadMethods.download_profile_photo' was never awaited RuntimeWarning: Enable tracemalloc to get the object allocation traceback /usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:30: RuntimeWarning: coroutine 'UpdateMethods._run_until_disconnected' was never awaited RuntimeWarning: Enable tracemalloc to get the object allocation traceback
在Jupyter上运行代码时。现在这是我的问题:
@
行开头的@client.on...
符号是什么意思?那条线应该做什么?从这一行开始,我不了解代码。如果您能帮助我理解它,将不胜感激。答案 0 :(得分:2)
Jupyter将运行asyncio
事件循环,以便您可以在async for / with / await
之外使用async def
。这与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,Python shell,正常运行),只需确保在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())
答案 1 :(得分:1)
只需添加await
和client.send_message('me', 'Hello, myself!')
即可解决该错误,并在download_profile_photo
完成工作后打印即可将图像下载到localhost
,因此这就是为什么您不这样做的原因看到什么。您应该通读telethon documentation和how to use photo downloads correctly
所有对客户端的调用都有一个延迟,应始终等待,这样才不会阻塞您的代码。您应该阅读asyncio tutorial 正确的代码是:
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()
@是修饰符,您应该阅读PEP related to decorators,但简而言之,它们先执行一个函数。
在这种情况下,@client.on(events.NewMessage
的意思是:
当有一个新事件碰巧是一条与指定模式匹配的消息时,请使用称为handler
的此函数对其进行处理