Telethon中await client(...)可运行但PyCharm报__await__警告的原因及正确写法
问题
使用Telethon框架编写调用Telegram API的异步代码可正常运行,但PyCharm IDE弹出警告:Class 'TelegramClient' does not define '__await__', so the 'await' operator cannot be used on its instances
代码如下:
async def main(): client = TelegramClient('test', api_id, api_hash) await client.start() result = await client(functions.payments.GetStarGiftsRequest(hash=0)) for i in result.gifts: print(f'''Имя: {i.title}, - id {i.id} - Stars: {i.stars}, - Сколько продаётся на рынке перепродажи: {i.availability_resale} - Осталось для покупки: {i.availability_remains} - Всего: {i.availability_total} - first_sale_date: {i.first_sale_date} - require_premium: {i.require_premium} - sold_out: {i.sold_out} - attributes:{i.sticker.attributes[1].alt}''') me = await client.get_entity('me') print(me) text = TextWithEntities('123', entities=[ MessageEntityBold(offset=0, length=12) ]) receiver_peer = await client.get_input_entity('@misha20062006') invoice = InputInvoiceStarGift(peer=receiver_peer, gift_id=bar_gift, hide_name=True, message=text) payment_form = await client(GetPaymentFormRequest(invoice=invoice)) try: pay = await client(functions.payments.SendStarsFormRequest( form_id=payment_form.form_id, invoice=invoice)) print(pay) except Exception as e: print('Ошибка: Слишком низкий баланс', e) asyncio.run(main())
警告原因
Telethon的TelegramClient类本身未定义__await__方法,但它实现了__call__方法,该方法会返回一个可等待对象(协程或Future)。PyCharm的静态代码分析无法识别这种动态的可等待逻辑,因此会误报警告——实际运行时,await client(...)是合法的,因为client()返回的是可等待对象,而非直接等待TelegramClient实例本身。
标准正确写法
有两种方式可以消除警告同时保持代码规范:
1. 显式调用client.invoke()方法
Telethon官方推荐使用client.invoke()替代直接调用client(),该方法的类型标注清晰,IDE可正确识别:
async def main(): client = TelegramClient('test', api_id, api_hash) await client.start() # 替换 await client(...) 为 await client.invoke(...) result = await client.invoke(functions.payments.GetStarGiftsRequest(hash=0)) for i in result.gifts: print(f'''Имя: {i.title}, - id {i.id} - Stars: {i.stars}, - Сколько продаётся на рынке перепродажи: {i.availability_resale} - Осталось для покупки: {i.availability_remains} - Всего: {i.availability_total} - first_sale_date: {i.first_sale_date} - require_premium: {i.require_premium} - sold_out: {i.sold_out} - attributes:{i.sticker.attributes[1].alt}''') me = await client.get_entity('me') print(me) text = TextWithEntities('123', entities=[ MessageEntityBold(offset=0, length=12) ]) receiver_peer = await client.get_input_entity('@misha20062006') invoice = InputInvoiceStarGift(peer=receiver_peer, gift_id=bar_gift, hide_name=True, message=text) payment_form = await client.invoke(GetPaymentFormRequest(invoice=invoice)) try: pay = await client.invoke(functions.payments.SendStarsFormRequest( form_id=payment_form.form_id, invoice=invoice)) print(pay) except Exception as e: print('Ошибка: Слишком низкий баланс', e) asyncio.run(main())
2. 使用上下文管理器优化代码
可以用async with上下文管理器自动处理客户端的连接与断开,无需手动调用start()和disconnect(),代码更简洁规范:
async def main(): async with TelegramClient('test', api_id, api_hash) as client: result = await client.invoke(functions.payments.GetStarGiftsRequest(hash=0)) for i in result.gifts: print(f'''Имя: {i.title}, - id {i.id} - Stars: {i.stars}, - Сколько продаётся на рынке перепродажи: {i.availability_resale} - Осталось для покупки: {i.availability_remains} - Всего: {i.availability_total} - first_sale_date: {i.first_sale_date} - require_premium: {i.require_premium} - sold_out: {i.sold_out} - attributes:{i.sticker.attributes[1].alt}''') me = await client.get_entity('me') print(me) text = TextWithEntities('123', entities=[ MessageEntityBold(offset=0, length=12) ]) receiver_peer = await client.get_input_entity('@misha20062006') invoice = InputInvoiceStarGift(peer=receiver_peer, gift_id=bar_gift, hide_name=True, message=text) payment_form = await client.invoke(GetPaymentFormRequest(invoice=invoice)) try: pay = await client.invoke(functions.payments.SendStarsFormRequest( form_id=payment_form.form_id, invoice=invoice)) print(pay) except Exception as e: print('Ошибка: Слишком низкий баланс', e) asyncio.run(main())
3. 抑制警告(不推荐)
如果坚持使用client()写法,可以添加# type: ignore注释让PyCharm忽略该警告:
result = await client(functions.payments.GetStarGiftsRequest(hash=0)) # type: ignore
内容的提问来源于stack exchange,提问作者Misha20062006
相关产品推荐
相关产品推荐

