繁体   English   中英

class 方法中的装饰器

[英]Decorators in class methods

我正在尝试在我的 class 中的方法上应用另一个 class 的装饰器...这是我对此电报 API 包装器库的实现: https://github.com/eternnoir/pyTelegramBotAPI

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

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()

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

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()

self虽然关键字更多的是所有方法的第一个参数的占位符变量名称,它始终是实例 object(除了classmethod ,其中第一个参数是 class 本身,而staticmethod两者都没有)

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

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

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

我认为正确的方法是使用 lambda 函数。 您可以向它传递多个参数并从外部 scope 获取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 命令

您应该在方法 start() 中设置 TeleBot() 的 object。

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()
class Variaveis:
    
    def __init__(self):
        self.bot = telebot.TeleBot(token='')

        @self.bot.message_handler(commands=["start"])
        def _process_command_start(message):
            self.process_command_start(message)

        self.bot.polling(none_stop=True, timeout=123)

    #----------------------------------------------------------------------------------------------------------------#
    # Começando a programar :
    
    def process_command_start(self, message):
        self.bot.send_message(message.chat.id, 'ola mundo')


Variaveis()

暂无
暂无

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

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