【问题标题】:How to wrap these decorated functions into a class?如何将这些装饰函数包装到一个类中?
【发布时间】:2019-11-07 18:04:54
【问题描述】:

我正在尝试将 V2 的 Slack API 封装到一个类中,以便我可以将有关我的机器人的信息封装起来。这是他们的示例 sn-ps 之一:

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 函数由于装饰器而被传递到 slack 对象中,所以如果我将它包装到一个类中,那么该函数并没有真正坐在我的类中。如何包装 say_hello 函数以使其能够调用属于我的类实例的方法和引用属性?

【问题讨论】:

    标签: python python-3.x class slack-api python-decorators


    【解决方案1】:

    他们的关键是根本不使用装饰器。

    从Markus的解决方案中,直接调用“run_on”函数,在调用“start”函数之前,类似如下:

    rtmclient = slack.RTMClient(token=self.Token)
    rtmclient.run_on(event='message')(self.handle_command)
    rtmclient.start()
    

    【讨论】:

      【解决方案2】:

      看看装饰器是如何工作的!

      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            
      

      【讨论】:

      • @Stoopkid 我也遇到了同样的问题,你是如何应用这个答案的?
      猜你喜欢
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 2021-05-10
      • 2013-11-17
      • 1970-01-01
      • 1970-01-01
      • 2017-11-05
      相关资源
      最近更新 更多