这与装饰器的工作方式相反吗?

时间:2019-07-18 15:44:15

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

昨天,我们在python中升级了slackclient模块,并需要根据此RTM API迁移指南更改一些代码。

https://github.com/slackapi/python-slackclient/wiki/Migrating-to-2.x

这是我的代码...

import slack

slack_token = os.environ['SLACK_BOT_TOKEN']

rtmclient = slack.RTMClient(token=slack_token)

@slack.RTMClient.run_on(event='message')
def parse_message(**payload):
    data = payload['data']
    channel_id = data['channel']
    print(data)
    print(channel_id)

rtmclient.start()

在此之前,我从未使用过Python装饰器。

在阅读了装饰器之后,据我了解,如果我要调用函数slack.RTMClient.run_on,则将调用装饰器parse_message

此代码似乎在做相反的事情。

为什么/ rtmclient.start()被调用时此代码如何工作?

1 个答案:

答案 0 :(得分:3)

不熟悉该特定API,但是

@slack.RTMClient.run_on(event='message')
def parse_message(**payload):
    ...

基本上相同
def parse_message(**payload):
    ...

parse_message = slack.RTMClient.run_on(event='message')(parse_message)

装饰器在调用函数时不被调用,而在其被声明时被调用。然后通常会定义并返回一个新函数,该函数将被调用,而不是原始函数,例如以及其他日志记录,备忘录等。

但是装饰器完全有可能只返回函数的原始版本 1 ,例如将其注册为某些事件的回调。

一个非常简化的示例:

my_callbacks = []
def register(f):
    my_callbacks.append(f)
    return f

@register
def foo():
    print("calling foo")


for f in my_callbacks:
    f()

1)如注释中所述,this decorator似乎甚至没有返回原始函数,而是None,这意味着该函数在修饰后将不再可直接调用,只能通过回调。