1. 程式人生 > 實用技巧 >八、常用的裝飾器

八、常用的裝飾器

1、常用的裝飾器有:before_request、after_request(這兩個裝飾器有點類似於django的中介軟體元件)

原始碼:

 1     def preprocess_request(self):
 2         """Called before the request is dispatched. Calls
 3         :attr:`url_value_preprocessors` registered with the app and the
 4         current blueprint (if any). Then calls :attr:`before_request_funcs`
5 registered with the app and the blueprint. 6 7 If any :meth:`before_request` handler returns a non-None value, the 8 value is handled as if it was the return value from the view, and 9 further request handling is stopped. 10 """ 11 12 bp = _request_ctx_stack.top.request.blueprint
13 14 funcs = self.url_value_preprocessors.get(None, ()) 15 if bp is not None and bp in self.url_value_preprocessors: 16 funcs = chain(funcs, self.url_value_preprocessors[bp]) 17 for func in funcs: 18 func(request.endpoint, request.view_args) 19 20 funcs = self.before_request_funcs.get(None, ())
21 if bp is not None and bp in self.before_request_funcs: 22 funcs = chain(funcs, self.before_request_funcs[bp]) 23 for func in funcs: 24 rv = func() 25 if rv is not None: 26 return rv
 1     def process_response(self, response):
 2         """Can be overridden in order to modify the response object
 3         before it's sent to the WSGI server.  By default this will
 4         call all the :meth:`after_request` decorated functions.
 5 
 6         .. versionchanged:: 0.5
 7            As of Flask 0.5 the functions registered for after request
 8            execution are called in reverse order of registration.
 9 
10         :param response: a :attr:`response_class` object.
11         :return: a new response object or the same, has to be an
12                  instance of :attr:`response_class`.
13         """
14         ctx = _request_ctx_stack.top
15         bp = ctx.request.blueprint
16         funcs = ctx._after_request_functions
17         if bp is not None and bp in self.after_request_funcs:
18             funcs = chain(funcs, reversed(self.after_request_funcs[bp]))
19         if None in self.after_request_funcs:
20             funcs = chain(funcs, reversed(self.after_request_funcs[None]))
21         for handler in funcs:
22             response = handler(response)
23         if not self.session_interface.is_null_session(ctx.session):
24             self.session_interface.save_session(self, ctx.session, response)
25         return response

練習:

 1 from flask import Flask, Markup, request, redirect
 2 
 3 
 4 app = Flask(__name__)
 5 
 6 
 7 # app.before_first_request_funcs -> list
 8 # 將被before_request裝飾的函式新增到before_first_request_funcs列表中,在檢視函式被執行前執行
 9 # 如果某個被裝飾的函式有返回值的,就會不在執行對應的檢視函式,直接開始執行被after_request裝飾器的函式(反向)
10 
11 
12 @app.before_request
13 def check_home():
14     if "home" in request.path:
15         return redirect("/")
16 
17 
18 @app.before_request
19 def usual_bye():
20     print("Bye")
21 
22 
23 @app.before_request
24 def usual_input():
25     print("Hello World!")
26 
27 
28 # app.after_request_funcs -> list
29 # 將被after_request裝飾的函式新增到after_request_funcs列表中,在響應產生後被執行,函式必須要有一個接收response的引數,並且也要返回
30 # 一個響應
31 # 注意:after_request_funcs裡面的函式執行的順序是相反的
32 
33 @app.after_request
34 def foo(response):
35     print("foo")
36     return response
37 
38 
39 @app.after_request
40 def bar(response):
41     print("bar")
42     return response
43 
44 
45 @app.route("/")
46 def index():
47     return Markup("index|<a href='/home'>Home</a>")
48 
49 
50 @app.route("/home")
51 def home():
52     return "home"
53 
54 
55 if __name__ == '__main__':
56     app.run("localhost", 80, debug=True)

圖示:

2、其他裝飾器:errorhandler、template_global、template_filter等

 1 # 當發生相應的錯誤碼時,執行對應的函式,返回一個介面良好的404介面
 2 @app.errorhandler(404)
 3 def show_404():
 4     from flask import render_template
 5     return render_template("404.html")
 6 
 7 
 8 # 可以讓所有的模板都使用的函式
 9 @app.template_global
10 def gun(a, b):
11     return a + b
12 
13 
14 # 可以讓所有的模板中都使用的過濾器
15 @app.template_filter
16 def f(a, b):
17     return a + b