使用定义为实例变量的装饰器函数
Using a decorator function defined as an instance variable
(虽然这个问题是专门针对Flask的,但可以按照标题概括)
我正在尝试在 class 中使用 Flask 的 app.route()
装饰器。但是,Flask 应用程序被初始化为一个实例变量,即 self.server
被设置为应用程序。这意味着我不能使用装饰器,因为 self
在装饰方法之外是未定义的。我希望能够做到以下几点:
class MyClass:
def __init__(self):
self.server = Flask(__name__)
@self.server.route('/')
def home():
return '<h1>Success</h1>'
这个问题有 work-arounds 吗?非常感谢任何帮助!
您可以在 __init__
方法的上下文中定义函数。然后,为了使函数能够正常调用,设置home
成员等于它。
class MyClass:
def __init__(self):
self.server = Flask(__name__)
# This is indented at __init__'s level, so a new instance of the function
# is defined every time __init__ runs. That means a new instance
# is defined for each instance of the class, and so it can be wrapped with
# the instance's "self" value.
@self.server.route('/')
def home_func():
return '<h1>Success</h1>'
# Then, you make it an object member manually:
self.home = home_func
我不确定您的总体用例是什么,但不将应用程序对象嵌入 class 而是使用 Flask 的 Pluggable Views 模块可能会更好。这将允许您将视图清晰地定义为继承自 flask.views.View 的 classes。示例:
import flask
import flask.views
class MyClass(flask.views.View):
def dispatch_request(self):
return '<h1>Success</h1>'
app.add_url_rule('/test', view_func=MyClass.as_view('home'))
鉴于这个小例子,这肯定是更多的代码,但这使您可以更灵活地定义其他 classes 或具有自己路由的函数,并且可能考虑使用 MethodViews,它为定义多个 HTTP 方法并将它们与单个 class.
相关联
您应该使用 self.server
对象的 add_url_rule
method 而不是使用 route()
装饰器,如下所示:
class MyClass:
def __init__(self):
self.server = Flask(__name__)
self.server.add_url_rule('/', 'home', self.home)
self.server.add_url_rule('/route-1', 'route-1', self.route_1)
self.server.add_url_rule('/route-2', 'route-2', self.route_2)
def home():
return '<h1>Success</h1>'
def route_1():
...
def route_2():
...
此模式允许您将路由处理程序定义为 class 上的方法,并且更易于阅读,因为您可以在一个块中看到所有 URL 规则。
(虽然这个问题是专门针对Flask的,但可以按照标题概括)
我正在尝试在 class 中使用 Flask 的 app.route()
装饰器。但是,Flask 应用程序被初始化为一个实例变量,即 self.server
被设置为应用程序。这意味着我不能使用装饰器,因为 self
在装饰方法之外是未定义的。我希望能够做到以下几点:
class MyClass:
def __init__(self):
self.server = Flask(__name__)
@self.server.route('/')
def home():
return '<h1>Success</h1>'
这个问题有 work-arounds 吗?非常感谢任何帮助!
您可以在 __init__
方法的上下文中定义函数。然后,为了使函数能够正常调用,设置home
成员等于它。
class MyClass:
def __init__(self):
self.server = Flask(__name__)
# This is indented at __init__'s level, so a new instance of the function
# is defined every time __init__ runs. That means a new instance
# is defined for each instance of the class, and so it can be wrapped with
# the instance's "self" value.
@self.server.route('/')
def home_func():
return '<h1>Success</h1>'
# Then, you make it an object member manually:
self.home = home_func
我不确定您的总体用例是什么,但不将应用程序对象嵌入 class 而是使用 Flask 的 Pluggable Views 模块可能会更好。这将允许您将视图清晰地定义为继承自 flask.views.View 的 classes。示例:
import flask
import flask.views
class MyClass(flask.views.View):
def dispatch_request(self):
return '<h1>Success</h1>'
app.add_url_rule('/test', view_func=MyClass.as_view('home'))
鉴于这个小例子,这肯定是更多的代码,但这使您可以更灵活地定义其他 classes 或具有自己路由的函数,并且可能考虑使用 MethodViews,它为定义多个 HTTP 方法并将它们与单个 class.
相关联您应该使用 self.server
对象的 add_url_rule
method 而不是使用 route()
装饰器,如下所示:
class MyClass:
def __init__(self):
self.server = Flask(__name__)
self.server.add_url_rule('/', 'home', self.home)
self.server.add_url_rule('/route-1', 'route-1', self.route_1)
self.server.add_url_rule('/route-2', 'route-2', self.route_2)
def home():
return '<h1>Success</h1>'
def route_1():
...
def route_2():
...
此模式允许您将路由处理程序定义为 class 上的方法,并且更易于阅读,因为您可以在一个块中看到所有 URL 规则。