RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1353189
Accepted
Twiss
Twiss
Asked:2022-04-24 00:31:24 +0000 UTC2022-04-24 00:31:24 +0000 UTC 2022-04-24 00:31:24 +0000 UTC

课堂上的第三方装饰师。面向对象

  • 772

问题。尽管没有调用类本身,但为什么此代码会按应有的方式重现。有一个假设是由于变量被调用的事实dp,但是我不清楚这有多可靠以及它有多实用。

from aiogram import Bot, Dispatcher, executor, types
import config

bot = Bot(token=config.TOKEN_TESTING, parse_mode=types.ParseMode.MARKDOWN_V2)
dp = Dispatcher(bot)

class SheduleBot:    
    @dp.message_handler(commands=['today' ])
    async def queue(message):
        await message.reply("```\nОтправь мне в личку сообщение```\n")



#shedule_bot = SheduleBot()
executor.start_polling(dp, skip_updates=True)
python
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    insolor
    2022-04-24T01:16:54Z2022-04-24T01:16:54Z

    尽管没有调用类本身,但为什么此代码会按应有的方式重现。

    类就在那里,它不是一个对象。为什么装饰器工作 - 因为类内的所有内容(方法的内容除外)在模块加载时立即执行(愚蠢的是,如果你print在方法之外的类内插入,它将在启动时工作)。因此,创建了方法并执行了装饰器。然后装饰器注册的方法通过调度程序简单地调用。

    演示代码,没有async,但本质是一样的:

    from collections import defaultdict
    from typing import List
    
    
    class Dispatcher:
        def __init__(self):
            self.functions = defaultdict(list)
    
        def message_hanlder(self, commands: List[str]):
            print("Внутри message_hanlder, commands =", commands)
            def decorator(func):
                print("Внутри декоратора на функции", func)
                # В данном случае декоратор ничем не оборачивает функцию
                # а просто регистрирует ее как обработчик команд
                # и возвращает ее же саму, а не wrapper
                for command in commands:
                    self.functions[command].append(func)
    
                return func
            print("Выходим из message_hanlder")
            return decorator
    
        def send_message(self, command: str, message: str):
            for func in self.functions[command]:
                func(message)
    
    
    dp = Dispatcher()
    
    
    class SomeClass:
        print("Внутри класса SomeClass")
    
        @dp.message_hanlder(commands=["yesterday", "today"])
        def handler1(message):
            print("Handler1:", message)
    
        print("Между методами класса SomeClass")
    
        @dp.message_hanlder(commands=["today", "tomorrow"])
        def handler2(message):
            print("Handler2:", message)
    
    
    print("Посылаем сообщения")
    dp.send_message(command="yesterday", message="Hello!")
    dp.send_message(command="today", message="Bye!")
    dp.send_message(command="tomorrow", message="Hello again!")
    

    结论:

    Внутри класса SomeClass
    Внутри message_hanlder, commands = ['yesterday', 'today']
    Выходим из message_hanlder
    Внутри декоратора на функции <function SomeClass.handler1 at 0x7fb610b3c1f0>
    Между методами класса SomeClass
    Внутри message_hanlder, commands = ['today', 'tomorrow']
    Выходим из message_hanlder
    Внутри декоратора на функции <function SomeClass.handler2 at 0x7fb610b3c280>
    Посылаем сообщения
    Handler1: Hello!
    Handler1: Bye!
    Handler2: Bye!
    Handler2: Hello again!
    

    那些。可以看出它print在类内部立即生效,并且装饰器在启动时立即执行。

    如果您还记得装饰器只是一个函数,它接收要装饰的函数并返回另一个函数(或者在这种情况下是相同的,但要装饰的函数由调度程序注册),那就更清楚了。所以这个类可以这样重写:

    class SomeClass:
        print("Внутри класса SomeClass")
    
        def handler1(message):
            print("Handler1:", message)
    
        handler1 = dp.message_hanlder(commands=["yesterday", "today"])(handler1)
        
        print("Между методами класса SomeClass")
    
        def handler2(message):
            print("Handler2:", message)
        
        handler2 = dp.message_hanlder(commands=["today", "tomorrow"])(handler2)
    

    在这种情况下,一切都会完全一样。

    装饰器是 dp 对象的方法这一事实不会以任何方式影响结果,如果装饰器是单独的函数,则行为将完全相同。

    • 2
  2. Vasily
    2022-04-24T00:38:31Z2022-04-24T00:38:31Z

    装饰器是一个包装器,允许您在函数之前或之后执行某些操作,在您的情况下,此装饰器称为,它在 Dispatcher-e (dp) 中注册您的消息处理程序并使用它来响应用户消息

    • 1

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5