python學習筆記-flask學習(一)

來源:互聯網
上載者:User

標籤:ping   item   nts   force   分析   resource   nic   elf   stat   

以下是一個簡單的能啟動並執行flask範例程式碼,從該範例程式碼中分析Flask源碼完成了哪些工作。

flask範例程式碼如下:

from flask import Flaskapp = Flask(__name__)@app.route(‘/‘)def hello_world():    return ‘Hello World!‘@app.route(‘/user/<name>‘)def user(name):    return ‘<h1>Hello,%s!<h1>‘%nameif __name__ == ‘__main__‘:    app.run(debug=True)

首先調用app = Flask(__name__)構建一個Flask執行個體。Flask類定義在app.py檔案中

 """The flask object implements a WSGI application and acts as the central    object.  It is passed the name of the module or package of the    application.  Once it is created it will act as a central registry for    the view functions, the URL rules, template configuration and much more.    The name of the package is used to resolve resources from inside the    package or the folder the module is contained in depending on if the    package parameter resolves to an actual python package (a folder with    an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file).

接下來分析app.route函數完成的工作

app.route是python的一個裝飾器具體的函數代碼如下:

 def route(self, rule, **options):        def decorator(f):            endpoint = options.pop(‘endpoint‘, None)            self.add_url_rule(rule, endpoint, f, **options)            return f        return decorator

在這裡主要是通過調用add_url_rule函數將app執行個體與對應的視圖函數關聯起來

 def add_url_rule(self, rule, endpoint=None, view_func=None, **options):        if endpoint is None:            endpoint = _endpoint_from_view_func(view_func)        options[‘endpoint‘] = endpoint        methods = options.pop(‘methods‘, None)        # if the methods are not given and the view_func object knows its        # methods we can use that instead.  If neither exists, we go with        # a tuple of only ``GET`` as default.        if methods is None:            methods = getattr(view_func, ‘methods‘, None) or (‘GET‘,)        if isinstance(methods, string_types):            raise TypeError(‘Allowed methods have to be iterables of strings, ‘                            ‘for example: @app.route(..., methods=["POST"])‘)        methods = set(item.upper() for item in methods)        # Methods that should always be added        required_methods = set(getattr(view_func, ‘required_methods‘, ()))        # starting with Flask 0.8 the view_func object can disable and        # force-enable the automatic options handling.        provide_automatic_options = getattr(view_func,            ‘provide_automatic_options‘, None)        if provide_automatic_options is None:            if ‘OPTIONS‘ not in methods:                provide_automatic_options = True                required_methods.add(‘OPTIONS‘)            else:                provide_automatic_options = False        # Add the required methods now.        methods |= required_methods        rule = self.url_rule_class(rule, methods=methods, **options)        rule.provide_automatic_options = provide_automatic_options        self.url_map.add(rule)        if view_func is not None:            old_func = self.view_functions.get(endpoint)            if old_func is not None and old_func != view_func:                raise AssertionError(‘View function mapping is overwriting an ‘                                     ‘existing endpoint function: %s‘ % endpoint)            self.view_functions[endpoint] = view_func
如果沒有指定endpoint函數_endpoint_from_view_func通過功能函數名指定為endpoint。接下來擷取指定methods。url_rule_class(rule, methods=methods, **options)產生一rule的執行個體。接著url_map.add(rule)將rule與flask執行個體關聯起來。在前面flask執行個體定義了Map對象的執行個體。
add函數的源碼如下:
    def add(self, rulefactory):        for rule in rulefactory.get_rules(self):            rule.bind(self)            self._rules.append(rule)            self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule)        self._remap = True

這裡將map與rule關聯起來。其中rule.bind()調用compile()對rule中的表達是進行了一次轉義以‘/static/<path:filename>‘為例。

    def compile(self):        if self.map.host_matching:            domain_rule = self.host or ‘‘        else:            domain_rule = self.subdomain or ‘‘        self._trace = []        self._converters = {}        self._weights = []        regex_parts = []        def _build_regex(rule):            for converter, arguments, variable in parse_rule(rule):                if converter is None:                    regex_parts.append(re.escape(variable))                    self._trace.append((False, variable))                    for part in variable.split(‘/‘):                        if part:                            self._weights.append((0, -len(part)))                else:                    if arguments:                        c_args, c_kwargs = parse_converter_args(arguments)                    else:                        c_args = ()                        c_kwargs = {}                    convobj = self.get_converter(                        variable, converter, c_args, c_kwargs)                    regex_parts.append(‘(?P<%s>%s)‘ % (variable, convobj.regex))                    self._converters[variable] = convobj                    self._trace.append((True, variable))                    self._weights.append((1, convobj.weight))                    self.arguments.add(str(variable))        _build_regex(domain_rule)        regex_parts.append(‘\\|‘)        self._trace.append((False, ‘|‘))        _build_regex(self.is_leaf and self.rule or self.rule.rstrip(‘/‘))        if not self.is_leaf:            self._trace.append((False, ‘/‘))        if self.build_only:            return        regex = r‘^%s%s$‘ % (            u‘‘.join(regex_parts),            (not self.is_leaf or not self.strict_slashes) and            ‘(?<!/)(?P<__suffix__>/?)‘ or ‘‘        )        self._regex = re.compile(regex, re.UNICODE)
_build_regex函數解析‘/static/<path:filename>‘。通過path去檢索轉換器
DEFAULT_CONVERTERS = {    ‘default‘:          UnicodeConverter,    ‘string‘:           UnicodeConverter,    ‘any‘:              AnyConverter,    ‘path‘:             PathConverter,    ‘int‘:              IntegerConverter,    ‘float‘:            FloatConverter,    ‘uuid‘:             UUIDConverter,}

在routing檔案中定義了PathConverter類。通過path字典中擷取。在這裡主要擷取的是regex = ‘[^/].*?‘這個屬性。然後regex_parts.append(‘(?P<%s>%s)‘ % (variable, convobj.regex))將‘filename‘和‘[^/].*?‘填充對應的字元。這裡產生對應的

urlRegex

 

 


python學習筆記-flask學習(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.