简体   繁体   English

如何避免将“全局”与 asyncio(电视节目)一起使用?

[英]How I can avoid using "global" with asyncio (telethon)?

As far as I know using "global" is a bad practice in python, but I have no idea how to avoid it here.据我所知,在 python 中使用“全局”是一种不好的做法,但我不知道如何在这里避免它。 Thank you in advance.先感谢您。

import asyncio
from telethon import TelegramClient, sync, events

api_id = ***
api_hash = '***'

client = TelegramClient('session_name', api_id, api_hash).start()

channel_id = ***

@client.on(events.NewMessage(chats=channel_id))
async def handler(event):
    text = event.raw_text.lower()

    global task

    if text == 'start':
        task = client.loop.create_task(main())
        await client.send_message(channel_id, 'task was started')

    if text == 'stop':
        task.cancel()
        await client.send_message(channel_id, 'task was canceled')

async def main():
    while True:
        await client.send_message(channel_id, 'do something')
        await asyncio.sleep(3)

client.run_until_disconnected()

Looking at the documentation, I couldn't find the recommended way to use the client with classes, but you should always be able to connect it yourself.查看文档,我找不到将客户端与类一起使用的推荐方法,但您应该始终能够自己连接它。 For example:例如:

class MyClient:
    def __init__(self, client):
        self.task = None
        self.client = client

    async def on_message(self, channel_id, event):
        text = event.raw_text.lower()

        if text == 'start':
            self.task = self.client.loop.create_task(self.main(channel_id))
            await self.client.send_message(channel_id, 'task was started')

        if text == 'stop':
            self.task.cancel()
            await self.client.send_message(channel_id, 'task was canceled')

    async def main(self, channel_id):
        while True:
            await self.client.send_message(channel_id, 'do something')
            await asyncio.sleep(3)

def run_client():
    # instantiate telegram client, my client, and connect the two
    api_id = ***
    api_hash = '***'

    channel_id = ***

    client = TelegramClient('session_name', api_id, api_hash).start()
    my_client = MyClient(client)

    @client.on(events.NewMessage(chats=channel_id))
    async def handle(event):
        await my_client.on_message(channel_id, event)

    client.run_until_disconnected()

run_client()

the TelegramClient's function:add_event_handler is what you're looking for TelegramClient 的 function:add_event_handler 是您正在寻找的

In general in Python, if you need a variable to be "static" (continue its lifetime beyond a single function call) like "task" in this example, you should consider going for an object-oriented approach, like @user4815162342 suggested.一般来说,在 Python 中,如果您需要一个变量是“静态的”(在单个 function 调用之后继续其生命周期),如本例中的“任务”,您应该考虑采用面向对象的方法,如 @user4815162342 建议的那样。 If you don't want classes and objects, you can also emulate a similar functionality using pre-set keyword arguments, although it's somewhat of an ugly hack.如果您不想要类和对象,您也可以使用预设关键字 arguments 模拟类似的功能,尽管它有点丑陋。 In your example, you would only have to change a single function like so:在您的示例中,您只需像这样更改单个 function :

@client.on(events.NewMessage(chats=channel_id))
async def handler(event, static_variables={}):
    text = event.raw_text.lower()

    if text == 'start':
        static_variables['task'] = client.loop.create_task(main())
        await client.send_message(channel_id, 'task was started')

    if text == 'stop':
        static_variables['task'].cancel()
        await client.send_message(channel_id, 'task was canceled')

The reason this works is that Python will only instantiate default arguments for keyword arguments on the first function call, and then re-use the instance (in this example, an initially empty dictionary) on all subsequent function calls. The reason this works is that Python will only instantiate default arguments for keyword arguments on the first function call, and then re-use the instance (in this example, an initially empty dictionary) on all subsequent function calls.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM