Python 这不正是装潢师的工作方式吗?

Python 这不正是装潢师的工作方式吗?,python,python-3.x,slack-api,python-decorators,Python,Python 3.x,Slack Api,Python Decorators,昨天,我们用python升级了slackclient模块,需要根据RTMAPI的迁移指南更改一些代码 这是我的密码 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 = pa

昨天,我们用python升级了slackclient模块,需要根据RTMAPI的迁移指南更改一些代码

这是我的密码

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装饰师合作过

在阅读了decorators之后,我的理解是,如果我调用函数
parse\u message
,则会调用decorator
slack.RTMClient.run\u on

这段代码似乎在做相反的事情


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

不熟悉该特定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)
调用函数时不调用decorator,而是在声明函数时调用decorator。然后,它通常会定义并返回一个新函数,该函数将被调用,而不是原始函数,例如,使用附加的日志记录、备忘录等

但装饰程序也完全有可能只返回函数的原始版本,但例如,将该函数注册为某些事件的回调

一个非常简单的例子:

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

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


for f in my_callbacks:
    f()

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

调用的是decorator,而不是您的函数,true,但decorator随后处理调用您的函数。根据decorator的编码方式,它可以调用您的函数,然后执行自己的逻辑,或者它可以执行自己的逻辑,然后调用您的函数(或者两者都执行)。装饰工是包装工。它将代码包装在函数周围,这样它就可以执行超出函数实际编程功能之外的附加逻辑。定义函数时会调用decorator。它只是定义
parse_message
的语法糖,后跟
parse_message=slack.RTMClient.run_on(event='message')(parse_message)
。也许装饰程序实际上并没有返回一个函数(无论是原始函数还是新函数)来绑定到
parse_message
,但如果没有明确调用函数的意图,那就无关紧要了。在这里,装饰器似乎用于注册回调。@错误这看起来像是注释中的答案。请把它作为一个答案贴出来。是的,在我写的时候,这个评论对我有点影响@tobias_k的回答涵盖了所有重要的方面。我们能不能停止说语法糖。这没什么意义。事实上,@chepner很有趣。当
decorator
返回
None
时,这意味着该函数在被修饰后将
None
,然后不再作为常规函数使用,而只能通过回调函数使用。