python学习笔记-flask学习(一)

以下是一个简单的能运行的flask示例代码,从该示例代码中分析Flask源码完成了哪些工作。

flask示例代码如下:

from flask import Flask

app = Flask(__name__)

@app.route(‘/‘)
def hello_world():
    return ‘Hello World!‘

@app.route(‘/user/<name>‘)
def user(name):
    return ‘<h1>Hello,%s!<h1>‘%name

if __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‘和‘[^/].*?‘填充对应的字符。这里生成对应的

url正则表达式

 
				
时间: 2024-12-27 01:51:34

python学习笔记-flask学习(一)的相关文章

[学习笔记]iphone学习小技巧

1. 版本控制 -- 是否响应某个方法 .查看当前系统版本. eg: [self respondsToSelector:@Selector(presentModalViewController:animated:)]//Yes:表示响应这个方法 [[UIDevice currentDevice].systemVersion floatValue] < 7.0 //判断当前系统是否小于7.0 2. 模态视图动画设置 eg: ModalViewController *modalVC = [[Moda

java JDK8 学习笔记——助教学习博客汇总

java JDK8 学习笔记——助教学习博客汇总 1-6章 (by肖昱) Java学习笔记第一章——Java平台概论 Java学习笔记第二章——从JDK到IDEJava学习笔记第三章——基础语法Java学习笔记第四章——认识对象 Java学习笔记第五章——对象封装 Java学习笔记第六章——继承与多态 7-10.12.14章 (by吴子怡) Java学习笔记JDK8>学习总结 11.13.15-18章 (by宋宸宁) 第11章 第13章第15章第16章第17章第18章

contiki-main.c 中的process系列函数学习笔记 &lt;contiki学习笔记之六&gt;

说明:本文依然依赖于 contiki/platform/native/contiki-main.c 文件. ------------------------------------------------------------------------------------------------------------------------------------- 根据上一个笔记里面添加的printf()语句的打印信息提示,hello world 打印是在执行了 1 autostart_

“Easy WebSockets with Flask and Gevent” 翻译学习笔记 ——Flask WebSocket使用快速入门

原文链接:http://blog.miguelgrinberg.com/post/easy-websockets-with-flask-and-gevent 介绍部分就先不翻了 This weekend I decided to take a short vacation from my book writing effort and spend time on a project I wanted to work on for a long time. The result of this e

【学习记录】关于makefile而进行的互联网学习技巧练习及学习笔记和学习心得记录(vs2010)

我也不知道作为一个完全的windows平台下的不怎么专业的软件工程学生,看到<Accelerated C++>的源代码,第一反应是:哦!我应该用make生成工程文件.然后我愉快的用AOL开始搜索相关资料. 然并卵!我一定是被什么奇怪的生物附身了.我应该直接用vs创建项目->导入文件.然后……ctrl+F5.多么完美. 可是……以下: [教程]来自于云风大大的blog(云风的 BLOG) IDE 不是程序员的唯一选择(一) 以及后面的(二)(三)(四) 以及大大写了一篇半,只为了说明用cl

selenium 学习笔记 ---新手学习记录(1) 问题总结

说明:每次学习各种语言时,环境搭建访问国外网址最头疼了,现在只要是工具下载好放到自己网盘,可以随时用. 1.首先工具准备,selenium需要用到的 下载地址 访问密码 ff8f 2.我选择的语言时junit eclipse开发 junit包下载: 下载 访问密码 c23d eclipse自己百度 3.实例练习. 具体步骤百度 4.遇见的问题 等待解决的 1).如下图,如何让变量pwds每次自动加1呢?假设pwds初始值为1,我想每次自动加1,向下图所示在我运行完${pwds}+1后我打印出来结

React 学习笔记(学习地址汇总)

好的博文地址:http://www.ruanyifeng.com/blog/2015/03/react.html 官网学习地址:http://facebook.github.io/react/docs/getting-started.html JSX语法地址:http://facebook.github.io/react/docs/displaying-data.html#jsx-syntax

ExtJs学习笔记之学习小结LoginDemo

ExtJs学习小结LoginDemo 1.示例:(登录界面) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="stylesheet" type="text/css" href="../ext-js-4.2.1/res

vray学习笔记(5)-学习资料

首先肯定是vray的官方的资料了: 一个是教程 https://docs.chaosgroup.com/display/VRAY3MAX/Tutorials 一个是帮助文件 https://docs.chaosgroup.com/display/VRAY3MAX bilibili.com以vray 3dsmax为关键字可以搜索到很多教程. http://www.aversis.be/tutorials/vray/vray-20-what-is-vray.htm doc88和百度文库上以vray