首页 > 解决方案 > 为什么烧瓶信号不适用于 lambdas?

问题描述

这有效:

from flask import Flask, request_started

app = Flask(__name__)
app.debug = True

def echo(sender, **extra):
    return print('request_started')

request_started.connect(echo)

@app.route('/')
def index():
    return 'index page'

虽然这不是:

from flask import Flask, request_started

app = Flask(__name__)
app.debug = True

request_started.connect(lambda sender, **extra: print('request_started'))

@app.route('/')
def index():
    return 'index page'

这是为什么?

第一个输出正确,而 lambda 什么也没给出,即没有错误。

我正在使用 python 3.6

显然,它与功能无关print,我也尝试过,但没有成功。

request_started.connect(lambda sender, **extra: open('output', 'w').write('request_started\n'))

〜更新〜

现在,这有效,我很困惑!

echo = lambda sender, **extra: print('request_started')
request_started.connect(echo)

标签: pythonflasklambda

解决方案


Flask 信号是使用blinker库实现的:https ://pythonhosted.org/blinker/index.html#blinker.base.Signal.connect

connect函数的签名是:

 connect(receiver, sender=ANY, weak=True)

文档中有关weak参数的内容如下:

——如果为真,信号将持有一个弱引用接收器,并在接收器超出范围或被垃圾收集时自动断开连接。默认为真

由于您的第一个示例使用默认参数 ofTrue并且没有其他对它的引用,lambda因此在呼叫完成后它会再次自动断开连接request_started.connect(lambda sender, **extra: print('request_started'))

在第二个版本

echo = lambda sender, **extra: print('request_started')
request_started.connect(echo)

lambda您在变量中保留对 的引用,echo以便信号连接直到echo超出范围(并且被垃圾收集)


推荐阅读