为什么flask信号不能与lambda一起使用?

时间:2018-12-27 20:33:12

标签: python flask lambda

这有效:

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)

1 个答案:

答案 0 :(得分:4)

Flask signals使用 blinker 库实现:https://pythonhosted.org/blinker/index.html#blinker.base.Signal.connect

connect函数的签名为:

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

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

  

–如果为true,则信号将对接收器和接收器保持弱引用   接收器超出范围或出现垃圾时自动断开连接   集。默认为True

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

在第二版中

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

您在变量lambda中保留对echo的引用,因此直到echo超出范围(并被垃圾回收)之前,信号一直处于连接状态