1. 程式人生 > >藍圖,轉載自其他網站,排版未優化

藍圖,轉載自其他網站,排版未優化

	<div class="copyright-area">原文出處: <a target="_blank" href="http://fanchunke.me/Flask/Flask%E4%B8%AD%E7%9A%84%E8%93%9D%E5%9B%BE%E7%AE%A1%E7%90%86/">Learn Python</a>&nbsp;&nbsp;&nbsp;</div><p>在<a href="http://python.jobbole.com/88591/">Flask中模組化應用的實現</a>一文中,我們曾分析過Flask 0.2版本中的<strong>Module</strong>類。
	這個類能夠實現Flask應用的多模組化管理。在0.7版本中,Flask重新設計了模組化管理的內容,提出了“藍圖”的概念,用來取代Module的功能。</p>

什麼是“藍圖”

官方文件中對“藍圖”的概念是這樣描述的:

Flask uses a concept of blueprints for making application components and supporting common patterns within an application or across applications. Blueprints can greatly simplify how large applications work and provide a central means for Flask extensions to register operations on applications. A Blueprint object works similarly to a Flask application object, but it is not actually an application. Rather it is a blueprint of how to construct or extend an application.

按照以上的描述,可以看出“藍圖”系統在Flask應用的元件化和擴充套件提供了很大的便利。“元件化”是指可以在Flask層上將一個Flask應用進行“分割”,實現模組化管理,這極大地簡化了構建大型應用的流程,也使得應用的維護變得更加容易。另外,“藍圖”還提供了一種Flask擴充套件在應用上註冊操作的核心方法。

“藍圖”和一個Flask應用物件很相似,但是並不是一個Flask應用物件。它是可以註冊到Flask應用上的一系列操作(對於此的理解,後文會詳細講到)。使用“藍圖”,可以實現以下的一些功能:

  • 將Flask應用“分割”為一系列“藍圖”的集合,簡化了大型應用工作的方式;
  • 在Flask應用上,以 URL 字首和或子域名註冊一個藍圖。可以以不同的URL多次註冊一個藍圖;
  • 通過藍圖提供模板過濾器、靜態檔案、模板和其它功能。

建立“藍圖”物件時發生了什麼

“藍圖”和Flask應用的工作方式非常相似。Flask中的“藍圖”系統能夠實現很多“藍圖”物件在應用層上的管理,這些“藍圖”物件可以共享應用配置。這意味著“藍圖”應該和Flask應用有一樣的執行邏輯,這樣一旦藍圖註冊到應用上,就可以完全像Flask應用一樣工作。

在Flask應用中有一些屬性,它們以字典的形式用來存放很多裝飾器執行的結果。例如:view_functions這個字典通常存放route裝飾器裝飾的檢視函式,可以用來進行URL匹配;before_request_functions字典會存放before_request裝飾器裝飾的檢視函式,當正式處理請求前會先執行這個字典中的函式••••••為了實現和Flask應用相同的請求處理邏輯,“藍圖”物件也設計了同樣的裝飾器函式,這些函式都是一些“匿名函式”,只要傳遞一個引數,就可以將本藍圖上的一些操作對映到Flask應用上去。

例如:before_request裝飾器

	<div id="crayon-5ba4e3476d5dc282730265" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切換是否顯示行編號"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="純文字顯示程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切換自動換行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="點選展開程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="複製程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新視窗中顯示程式碼"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">def before_request(self, f):
"""Like :meth:`Flask.before_request` but for a blueprint.  This function
is only executed before each request that is handled by a function of
that blueprint.
"""
self.record_once(lambda s: s.app.before_request_funcs
    .setdefault(self.name, []).append(f))
return f</textarea></div>
		<div class="crayon-main" style="position: relative; z-index: 1;">
			<table class="crayon-table">
				<tbody><tr class="crayon-row">
			<td class="crayon-nums " data-settings="show">
				<div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;"><div class="crayon-num" data-line="crayon-5ba4e3476d5dc282730265-1">1</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5dc282730265-2">2</div><div class="crayon-num" data-line="crayon-5ba4e3476d5dc282730265-3">3</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5dc282730265-4">4</div><div class="crayon-num" data-line="crayon-5ba4e3476d5dc282730265-5">5</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5dc282730265-6">6</div><div class="crayon-num" data-line="crayon-5ba4e3476d5dc282730265-7">7</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5dc282730265-8">8</div></div>
			</td>
					<td class="crayon-code"><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="crayon-5ba4e3476d5dc282730265-1"><span class="crayon-r">def</span><span class="crayon-h"> </span><span class="crayon-e">before_request</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">f</span><span class="crayon-sy">)</span><span class="crayon-o">:</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5dc282730265-2"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">"""Like :meth:`Flask.before_request` but for a blueprint.&nbsp;&nbsp;This function</span></div><div class="crayon-line" id="crayon-5ba4e3476d5dc282730265-3"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;is only executed before each request that is handled by a function of</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5dc282730265-4"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;that blueprint.</span></div><div class="crayon-line" id="crayon-5ba4e3476d5dc282730265-5"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;"""</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5dc282730265-6"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-e">record_once</span><span class="crayon-sy">(</span><span class="crayon-r">lambda</span><span class="crayon-h"> </span><span class="crayon-v">s</span><span class="crayon-o">:</span><span class="crayon-h"> </span><span class="crayon-v">s</span><span class="crayon-sy">.</span><span class="crayon-v">app</span><span class="crayon-sy">.</span><span class="crayon-v">before_request</span><span class="crayon-sy">_</span>funcs</div><div class="crayon-line" id="crayon-5ba4e3476d5dc282730265-7"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-sy">.</span><span class="crayon-e">setdefault</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">)</span><span class="crayon-sy">.</span><span class="crayon-e">append</span><span class="crayon-sy">(</span><span class="crayon-v">f</span><span class="crayon-sy">)</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5dc282730265-8"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">return</span><span class="crayon-h"> </span><span class="crayon-v">f</span></div></div></td>
				</tr>
			</tbody></table>
		</div>
	</div>

上面的程式碼中,只要給這個裝飾器傳遞引數s,那麼這個裝飾器就會將裝飾的函式新增到Flask應用的before_request_functions字典當中,並且和該“藍圖”的名字對應起來。這樣就可以實現該函式在Flask應用中可用。

由於“藍圖”的建立過程和Flask應用的建立過程是分離的,所以在“藍圖”中使用裝飾器不會立即對應用產生效果。“藍圖”中裝飾器函式的返回值會經過record_once方法儲存在“藍圖”物件的deferred_functions列表中,這為“藍圖”物件的註冊提供了一個介面:只要在註冊“藍圖”時執行deferred_functions列表中的函式即可。

以下是一個簡單的例子:

	<div id="crayon-5ba4e3476d5e5712970581" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切換是否顯示行編號"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="純文字顯示程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切換自動換行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="點選展開程式碼" style="display: none;"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="複製程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新視窗中顯示程式碼"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;"># blueprint

>>> from flask import Blueprint >>> blog = Blueprint(‘blog’, name, static_folder=‘static’, template_folder=‘templates’) >>> @blog.route(’/’) def index(): return “This is blog home page.” >>> @blog.before_request def before_request(): return “This is before_request function.” >>> @blog.after_request def after_request(): return “This is after_request function.” >>> @blog.after_app_request def after_app_request(): return “This is after_app_request function.”

1234567891011121314151617 # blueprint>>>fromflask importBlueprint>>>blog=Blueprint(‘blog’,name,static_folder=‘static’,template_folder=‘templates’)>>>@blog.route(’/’)defindex():return“This is blog home page.”>>>@blog.before_requestdefbefore_request():return“This is before_request function.”>>>@blog.after_requestdefafter_request():return“This is after_request function.”>>>@blog.after_app_requestdefafter_app_request():return“This is after_app_request function.”

上面的例子中:

  • 首先我們建立了一個“藍圖”物件blog。建立“藍圖”物件時,必須至少傳遞前兩個引數:nameimport_name。也可以傳遞static_foldertemplate_folderurl_prefix等引數,url_prefix引數也可以在註冊藍圖時傳入。
  • 之後,我們為blog增加了四條檢視函式,每個函式由藍圖的裝飾器裝飾。此時,我們看一下“藍圖”物件的deferred_functions中有什麼:
    	<div id="crayon-5ba4e3476d5ea038979096" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
    	
    		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
    		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切換是否顯示行編號"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="純文字顯示程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切換自動換行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="點選展開程式碼" style="display: none;"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="複製程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新視窗中顯示程式碼"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
    		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
    		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">&gt;&gt;&gt; blog.deferred_functions
    

[<function flask.blueprints.<lambda>>, <function flask.blueprints.<lambda>>, <function flask.blueprints.<lambda>>, <function flask.blueprints.<lambda>> ]

123456 >>>blog.deferred_functions[<function flask.blueprints.<lambda>>,<function flask.blueprints.<lambda>>,<function flask.blueprints.<lambda>>,<function flask.blueprints.<lambda>>]

可以看出,此時“藍圖”物件的deferred_functions中已經包含了四個匿名函式,分別對應上面例子中的四個檢視函式。一旦“藍圖”被註冊到應用上,會執行這四個函式。

註冊“藍圖”

Flask應用和“藍圖”中都有註冊“藍圖”的介面。

Flask應用 中的介面是:

	<div id="crayon-5ba4e3476d5ee127410963" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切換是否顯示行編號"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="純文字顯示程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切換自動換行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="點選展開程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="複製程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新視窗中顯示程式碼"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">def register_blueprint(self, blueprint, **options):
"""Registers a blueprint on the application.
.. versionadded:: 0.7
"""
first_registration = False
if blueprint.name in self.blueprints:
    assert self.blueprints[blueprint.name] is blueprint, \
        'A blueprint\'s name collision ocurred between %r and ' \
        '%r.  Both share the same name "%s".  Blueprints that ' \
        'are created on the fly need unique names.' % \
        (blueprint, self.blueprints[blueprint.name], blueprint.name)
else:
    self.blueprints[blueprint.name] = blueprint
    first_registration = True
blueprint.register(self, options, first_registration)</textarea></div>
		<div class="crayon-main" style="position: relative; z-index: 1;">
			<table class="crayon-table">
				<tbody><tr class="crayon-row">
			<td class="crayon-nums " data-settings="show">
				<div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;"><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-1">1</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-2">2</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-3">3</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-4">4</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-5">5</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-6">6</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-7">7</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-8">8</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-9">9</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-10">10</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-11">11</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-12">12</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-13">13</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-14">14</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-15">15</div></div>
			</td>
					<td class="crayon-code"><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-1"><span class="crayon-r">def</span><span class="crayon-h"> </span><span class="crayon-e">register_blueprint</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">blueprint</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-o">*</span><span class="crayon-o">*</span><span class="crayon-v">options</span><span class="crayon-sy">)</span><span class="crayon-o">:</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-2"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">"""Registers a blueprint on the application.</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-3"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;.. versionadded:: 0.7</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-4"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;"""</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-5"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">first_registration</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">False</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-6"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">if</span><span class="crayon-h"> </span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-e">name </span><span class="crayon-st">in</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">blueprints</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-7"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">assert</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">blueprints</span><span class="crayon-sy">[</span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">]</span><span class="crayon-h"> </span><span class="crayon-st">is</span><span class="crayon-h"> </span><span class="crayon-v">blueprint</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-sy">\</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-8"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">'A blueprint\'s name collision ocurred between %r and '</span><span class="crayon-h"> </span><span class="crayon-sy">\</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-9"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">'%r.&nbsp;&nbsp;Both share the same name "%s".&nbsp;&nbsp;Blueprints that '</span><span class="crayon-h"> </span><span class="crayon-sy">\</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-10"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">'are created on the fly need unique names.'</span><span class="crayon-h"> </span><span class="crayon-o">%</span><span class="crayon-h"> </span><span class="crayon-sy">\</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-11"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-sy">(</span><span class="crayon-v">blueprint</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">blueprints</span><span class="crayon-sy">[</span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">]</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-12"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">else</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-13"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">blueprints</span><span class="crayon-sy">[</span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">]</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">blueprint</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-14"><span class="crayon-e">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">first_registration</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">True</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-15"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-e">register</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">options</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">first_registration</span><span class="crayon-sy">)</span></div></div></td>
				</tr>
			</tbody></table>
		</div>
	</div>

這個方法首先會對“藍圖”進行檢查,如果已經註冊,則會出現一條assert語句。否則,就會呼叫“藍圖”物件的register方法進行註冊。

藍圖物件 中的介面是:

	<div id="crayon-5ba4e3476d5f2371270261" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切換是否顯示行編號"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="純文字顯示程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切換自動換行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="點選展開程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="複製程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新視窗中顯示程式碼"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important; margin-top: -18px; display: none;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">def register(self, app, options, first_registration=False):
"""Called by :meth:`Flask.register_blueprint` to register a blueprint
on the application.  This can be overridden to customize the register
behavior.  Keyword arguments from
:func:`~flask.Flask.register_blueprint` are directly forwarded to this
method in the `options` dictionary.
"""
self._got_registered_once = True
state = self.make_setup_state(app, options, first_registration)
if self.has_static_folder:
    state.add_url_rule(self.static_url_path + '/&lt;path:filename&gt;',
                       view_func=self.send_static_file,
                       endpoint='static')
for deferred in self.deferred_functions:
    deferred(state)</textarea></div>
		<div class="crayon-main" style="position: relative; z-index: 1;">
			<table class="crayon-table">
				<tbody><tr class="crayon-row">
			<td class="crayon-nums " data-settings="show">
				<div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;"><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-1">1</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-2">2</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-3">3</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-4">4</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-5">5</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-6">6</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-7">7</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-8">8</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-9">9</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-10">10</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-11">11</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-12">12</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-13">13</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-14">14</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-15">15</div></div>
			</td>
					<td class="crayon-code"><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-1"><span class="crayon-r">def</span><span class="crayon-h"> </span><span class="crayon-e">register</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">app</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">options</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">first_registration</span><span class="crayon-o">=</span><span class="crayon-t">False</span><span class="crayon-sy">)</span><span class="crayon-o">:</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-2"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">"""Called by :meth:`Flask.register_blueprint` to register a blueprint</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-3"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;on the application.&nbsp;&nbsp;This can be overridden to customize the register</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-4"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;behavior.&nbsp;&nbsp;Keyword arguments from</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-5"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;:func:`~flask.Flask.register_blueprint` are directly forwarded to this</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-6"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;method in the `options` dictionary.</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-7"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;"""</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-8"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">_got_registered_once</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">True</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-9"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">state</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-e">make_setup_state</span><span class="crayon-sy">(</span><span class="crayon-v">app</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">options</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">first_registration</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-10"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">if</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">has_static_folder</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-11"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">state</span><span class="crayon-sy">.</span><span class="crayon-e">add_url_rule</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">static_url_path</span><span class="crayon-h"> </span><span class="crayon-o">+</span><span class="crayon-h"> </span><span class="crayon-s">'/&lt;path:filename&gt;'</span><span class="crayon-sy">,</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-12"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="crayon-v">view_func</span><span class="crayon-o">=</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">send_static_file</span><span class="crayon-sy">,</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-13"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="crayon-v">endpoint</span><span class="crayon-o">=</span><span class="crayon-s">'static'</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-14"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">for</span><span class="crayon-h"> </span><span class="crayon-e">deferred </span><span class="crayon-st">in</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">deferred_functions</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-15"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-e">deferred</span><span class="crayon-sy">(</span><span class="crayon-v">state</span><span class="crayon-sy">)</span></div></div></td>
				</tr>
			</tbody></table>
		</div>
	</div>

藍圖物件中的register方法首先會生成一個BlueprintSetupState物件,這個物件將當前應用和當前藍圖的相關資訊進行關聯,還將作為引數傳遞到藍圖物件deferred_functions列表中的每一個函式。這樣,藍圖中的相關操作就會對映到當前應用當中。

還是以上面的例子為例:

	<div id="crayon-5ba4e3476d5f6353833035" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切換是否顯示行編號"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="純文字顯示程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切換自動換行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="點選展開程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="複製程式碼"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新視窗中顯示程式碼"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">&gt;&gt;&gt; from flask import Flask

>>> app = Flask(name) >>> app.url_map Map([<Rule ‘/static/<filename>’ (HEAD, OPTIONS, GET) -> static>]) >>> app.blueprints {} >>> app.before_request_funcs {} >>> app.after_request_funcs {} >>> app.register_blueprint(blog, url_prefix=’/blog’) >>> app.url_map Map([<Rule ‘/blog/’ (HEAD, OPTIONS, GET) -> blog.index>, <Rule ‘/blog/static/<filename>’ (HEAD, OPTIONS, GET) -> blog.static>, <Rule ‘/static/<filename>’ (HEAD, OPTIONS, GET) -> static> ]) >>> app.blueprints {‘blog’: <flask.blueprints.Blueprint at 0x896e7f0>} >>> app.before_request_funcs {‘blog’: [<function main.before_request>]} >>> app.after_request_funcs {None: [<function main.after_app_request>], ‘blog’: [<function main.after_request>] }

123456789101112131415161718192021222324 >>>fromflask importFlask>>>app=Flask(name)>>>app.url_mapMap([<Rule‘/static/<filename>’(HEAD,OPTIONS,GET)->static>])>>>app.blueprints{}>>>app.before_requestfuncs{}>>>app.after_requestfuncs{}>>>app.register_blueprint(blog,url_prefix=’/blog’)>>>app.url_mapMap([<Rule‘/blog/’(HEAD,OPTIONS,GET)->blog.index>,<Rule‘/blog/static/<filename>’(HEAD,OPTIONS,GET)->blog.static>,<Rule‘/static/<filename>’(HEAD,OPTIONS,GET)->static>])>>>app.blueprints{‘blog’:<flask.blueprints.Blueprint at0x896e7f0>}>>>app.before_requestfuncs{‘blog’:[<function main.before_request>]}>>>app.after_requestfuncs{None:[<function main.after_app_request>],‘blog’:[<function main.after_request>]}

經過上面的例子,可以發現“藍圖”物件註冊到Flask應用時,會在Flask應用對應的地方增加“藍圖”物件的相關資訊。例如,blog物件中有一個before_request裝飾器,註冊成功後,在app.before_request_funcs增加了該資訊,並且以藍圖名作為鍵進行區分。blog物件中還有一個route裝飾器,它為藍圖增加了一條URL規則,最終會在Flask應用的url_map中出現。由於在建立藍圖時我們增加了static_folder引數,所以在url_map中我們還可以看到‘/blog/static/<filename>’這樣的URL規則。

<div class="post-adds">
    <span data-post-id="88587" class=" btn-bluet-bigger href-style vote-post-up   register-user-only "><i class="fa  fa-thumbs-o-up"></i> <h10 id="88587votetotal">1</h10> 贊</span>
    <span data-book-type="1" data-site-id="13" data-item-id="88587" data-item-type="1" class=" btn-bluet-bigger href-style bookmark-btn  register-user-only "><i class="fa fa-bookmark-o  "></i> 1 收藏</span>

                <a href="#article-comment"><span class="btn-bluet-bigger href-style hide-on-480"><i class="fa fa-comments-o"></i>  評論</span></a>
    
    
    
    <!-- JiaThis Button BEGIN -->
    <div class="jiathis_style_24x24" style="display: inline-flex; position: relative; margin: 0; clear: both;float: right;">
        <a class="jiathis_button_tsina"></a>
        <a class="jiathis_button_weixin"></a>
        <a class="jiathis_button_qzone"></a>
        <a class="jiathis_button_fb hide-on-480"></a>
        <a href="http://www.jiathis.com/share?uid=1745061" class="jiathis jiathis_txt jiathis