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

问题描述 投票:3回答:1

这有效:

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)
python flask lambda
1个回答
4
投票

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

connect函数的签名是:

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

随着文档说明有关weak参数的以下内容:

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超出范围(并且是垃圾收集)

© www.soinside.com 2019 - 2024. All rights reserved.