How to pass Python object to a class before it's initialization

83 views Asked by At

I'm researching aiogram module for Telegram bots. Handlers for messages from Telegram are decorated with @dp..... wrappers where dp = Dispatcher(). All examples in docs are about one file code. So, it works as follows:

...
dp = Dispatcher(bot)
...
@dp.message_handler(commands=['start', 'help'])
async def send_welcome(message: types.Message):
    ....

So here no problem - we initialize dp and then use it in handlers functions. What if we separate code to different files - how to pass dp object from main file to other modules? I mean we can't pass dp as an argument to handlers functions because it is used not inside the function but to describe (wrap) it before usage. I believe this should be kind of a regular task but for some reason didn't find an answer.

Should we use some kind of functions constructors? So that we pass dp to function-constructor that then creates another function wrapping it in the moment of creation?

1

There are 1 answers

0
Aaron Bentley On

You can just import it normally. When you do dp = Dispatcher(bot), you're adding it to the current module's namespace.

However, you can't keep dp in the main module. Because that would mean the other modules would need to import main, but also be imported by main. That's an import loop.

But you can define dp in e.g. other.py and have main import dp from other.

main.py:
from other import dp, baz


@dp
def foo(*args, **kwargs):
    print("hello")


if __name__ == '__main__':
    foo('bar')
    baz('bar')


other.py:

def Dispatcher(obj):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(args)
            func(*args, **kwargs)
        return wrapper
    return decorator


dp = Dispatcher(object())


@dp
def baz(*args, **kwargs):
    print("Hi")