如何通过flask.Blueprint.route装饰器传递类的self?

6 投票
1 回答
6884 浏览
提问于 2025-04-17 06:34

我正在用Flask和Python 2.7编写我网站的后台,遇到了一点问题。我喜欢用类来封装我的函数,这样可以让代码看起来更整洁,也方便我保持模块化。不过,我遇到的一个问题是,Flask用来处理路由的装饰器没有保留self变量。我用self来访问类中的loadDb方法。请看下面的代码。有没有人知道这是为什么,或者有什么办法可以解决这个问题?

class Test(object):
    blueprint = Blueprint("Test", __name__)
    def __init__(self, db_host, db_port):
        self.db_host = db_host
        self.db_port = db_port
    def loadDb(self):
        return Connection(self.db_host, self.db_port)
    @blueprint.route("/<var>")
    def testView(var): # adding self here gives me an error
        return render_template("base.html", myvar=self.loadDb().find({"id": var})

1 个回答

9

如果你在方法中加上 self,就会出错,因为这个方法在装饰器中和函数的工作方式是一样的,而 Flask 不期待第一个参数是 self 的函数。

我们来看一下 route 的代码: https://github.com/pallets/flask/blob/master/src/flask/blueprints.py#L52

它调用了 self.add_url_rule(这里的 self 是指 Blueprint),并传入了一些参数,其中一个就是函数。你想要的是把规则添加到一个 Test 的实例方法上(也就是 self.testView),而不是直接用方法本身(Test.testview)。这有点棘手,因为装饰器是在类创建的时候执行的,那时还没有任何实例存在。

我能建议的解决办法,除了避免把视图作为类的方法外,就是在 Test 的构造函数中调用 blueprint.add_url_rule(也就是说,在 Test 的实例第一次被创建时)。

撰写回答