Python 类方法中的装饰器

Python 类方法中的装饰器,python,telegram,telegram-bot,python-decorators,Python,Telegram,Telegram Bot,Python Decorators,我正在尝试在我的类中的方法上应用另一个类的decorator。。。 这是我对电报API包装器库的实现: 但在我的示例中,我不想从脚本中使用它,而是想将其用作类的方法,如下所示: class Bot: def __init__(self, key): self.key = key self.bot=telebot.TeleBot(key) def start(self): self.bot.polling() # Ha

我正在尝试在我的类中的方法上应用另一个类的decorator。。。 这是我对电报API包装器库的实现:

但在我的示例中,我不想从脚本中使用它,而是想将其用作类的方法,如下所示:

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
尽管关键字更像是始终是实例对象的所有方法的第一个参数的占位符变量名(除了
classmethod
其中第一个参数是类本身,而
staticmethod
中没有)

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

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


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

,对于那些可能需要它的人-我发现的解决方案-是将函数放在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()

我认为正确的方法是使用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命令。

您不应该将密钥存储在类中的变量中。只需传递它并使用它即可。你有没有试过在没有self关键字的情况下使用它?真的有效吗?
send_message
echo_message
在init方法中定义。我不认为你可以通过bot方法访问它们
x.send\u welcome('some\u message')
将引发
AttributeError
hi-是的,它可以工作-因为我实际上从未访问过它们:它是一种分配的事件处理程序。。。所以它起作用了