Как обернуть эти декорированные функции в класс? - PullRequest
0 голосов
/ 25 июня 2019

Я пытаюсь обернуть V2 Slack API в класс, чтобы хранить информацию о моем боте в инкапсуляции.Вот один из их примеров фрагментов:

import slack

slack_token = os.environ["SLACK_API_TOKEN"]
rtmclient = slack.RTMClient(token=slack_token)

@slack.RTMClient.run_on(event='message')
def say_hello(**payload):
    data = payload['data']
    if 'Hello' in data['text']:
        channel_id = data['channel']
        thread_ts = data['ts']
        user = data['user']

        webclient = payload['web_client']
        webclient.chat_postMessage(
            channel=channel_id,
            text="Hi <@{}>!".format(user),
            thread_ts=thread_ts
        )

rtmclient.start()

Насколько я понимаю, эта функция say_hello передается в слабый объект из-за декоратора, поэтому, если бы я обернул это в класс,эта функция на самом деле не сидит внутри моего класса.Как обернуть функцию say_hello, чтобы она могла вызывать методы и ссылочные свойства, которые принадлежали экземпляру моего класса?

1 Ответ

1 голос
/ 26 июня 2019

Посмотрите, как работают декораторы!

def decorator_factory(f):                                                                                                                                                                     
    def decoration(*args, **kwargs):                                                                                                                                                          
        print('before')                                                                                                                                                                       
        r = f(*args, **kwargs)                                                                                                                                                                
        print('after')                                                                                                                                                                        
        return r                                                                                                                                                                              
    return decoration                                                                                                                                                                         

@decorator_factory                                                                                                                                                                            
def inc(i):                                                                                                                                                                                   
    '''                                                                                                                                                                                       
    >>> inc(23)                                                                                                                                                                               
    before                                                                                                                                                                                    
    after                                                                                                                                                                                     
    42                                                                                                                                                                                        
    '''                                                                                                                                                                                       
    return i + 1

Возможно, существует лучший канонический способ достичь того, чего вы хотите, но это поможет:

class Client():                                                                                                                                                                               

    def __init__(self):                                                                                                                                                                       
        slack.RTMClient.run_on(event='message')(self.decorated)                                                                                                                               

    def decorated(self, x, y, z):                                                                                                                                                                      
        pass            
...