【问题标题】:Decorators in class methods类方法中的装饰器
【发布时间】:2020-09-03 09:02:00
【问题描述】:

我正在尝试将另一个类的装饰器应用于我的类中的方法... 这是我对这个 Telegram API 包装库的实现: https://github.com/eternnoir/pyTelegramBotAPI

但在我的示例中,我不想从脚本中使用它——而是像这样的类方法:

class Bot:

    def __init__(self, key):
        self.key = key
        self.bot=telebot.TeleBot(key)

    def start(self):
        self.bot.polling()

    # Handle '/start' and '/help'
    @self.bot.message_handler(commands=['help', 'start'])
    def send_welcome(self,message):
        self.bot.reply_to(message, """\
        Hi there, I am EchoBot. \
        I am here to echo your kind words back to you. \
        Just say anything nice and I'll say the exact same thing to you!\
        """)


    # Handle all other messages with content_type 'text' (content_types defaults to ['text'])
    @self.bot.message_handler(func=lambda message: True)
    def echo_message(message):
        self.bot.reply_to(message, message.text)

所有self 都被突出显示......当然不能正常工作 - 如果有人能解释我做错了什么会很高兴? 尝试自定义的原始示例是:

import telebot

bot = telebot.TeleBot("TOKEN")

@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
    bot.reply_to(message, "Howdy, how are you doing?")

@bot.message_handler(func=lambda message: True)
def echo_all(message):
    bot.reply_to(message, message.text)

bot.polling()

【问题讨论】:

  • 您不应该将密钥存储在类的变量中。只需传递并使用它。您是否尝试过在不使用 self 关键字的情况下使用它?

标签: python telegram telegram-bot python-decorators


【解决方案1】:

对于那些可能需要它的人 - 我找到的解决方案 - 是将函数放在 Ctor 中 - 而不是将装饰器应用于类方法....:

class Bot:

def __init__(self, key,greting):
    self.key = key
    self.bot=telebot.TeleBot(key)
    self.greting=greting

    # Handle '/start' and '/help'
    @self.bot.message_handler(commands=['help', 'start'])
    def send_welcome(self, message):
        self.bot.reply_to(message,self.greting )

    # Handle all other messages with content_type 'text' (content_types defaults to ['text'])
    @self.bot.message_handler(func=lambda message: True)
    def echo_message(message):
        self.bot.reply_to(message, message.text)

def start(self):
    x = threading.Thread(name=self.greting, target=self.bot.polling,)
    x.start()

【讨论】:

  • 真的有用吗? send_message 和 echo_message 在 init 方法中定义。我认为您不能将它们作为机器人方法访问。 x.send_welcome('some_message') 将提高 AttributeError
  • 嗨 - 是的,它有效 - 因为我实际上从未访问过它们:它是一种分配的事件处理程序......所以它有效
【解决方案2】:

self 虽然关键字更像是所有方法的第一个参数的占位符变量名,但始终是实例对象(classmethod 除外,其中第一个参数是类本身,staticmethod 两者都没有)

对于任何方法,即使您使用this 而不是self 作为任何方法的第一个参数,您也可以使用this.foo 访问所有对象属性或使用this.bar() 访问方法。

所以从技术上讲,您无法在任何方法之外访问该对象。装饰器位于您无法访问对象的最外层(仅作为第一个参数传递给方法)

我能想到的一个复杂且不必要的解决方法是编写一个静态方法来帮助您从参数中捕获self 对象,然后访问它的message_handler

【讨论】:

    【解决方案3】:

    我认为正确的方法是使用 lambda 函数。您可以向它传递多个参数并从外部范围获取 self。

    所以,我完成了下一个示例

    import telebot
    
    
    class Telegram:
        def __init__(self, token):
            self.channel = telebot.TeleBot(token, parse_mode=None)
    
            start_dict = dict(
                function=lambda msg, obj=self: obj.start_handler(msg),
                filters=dict(
                    commands=["start"],
                )
            )
            self.channel.add_message_handler(start_dict)
    
            self.channel.polling()
    
        def start_handler(self, message):
            print("START command")
    
    
    test = Telegram("your-token-here")
    

    您可以从控制台运行它,每次发送 /start 给它时它都会打印 START 命令。

    【讨论】:

      【解决方案4】:

      你应该在 start() 方法中设置 TeleBot() 的对象。

      import telebot
      from decouple import config as key
      
      class TelegramBot():
          def bot(self):
              bot = telebot.TeleBot(key('token'))
      
              @bot.message_handler(commands=['start'])
              def start(message):
                  bot.send_message(message.chat.id, "Sup, Sani :)")
              
              bot.polling(none_stop=True)
      
      TelegramBotSpot().bot()
      

      【讨论】:

        猜你喜欢
        • 2014-01-14
        • 2020-01-11
        • 1970-01-01
        • 2022-01-06
        • 2012-02-09
        • 1970-01-01
        • 2014-04-08
        • 1970-01-01
        • 2012-09-11
        相关资源
        最近更新 更多