Python Flask+Pandas+Plotly实战(一)

  • Post author:
  • Post category:python

我不是一个伟大的程序员,我只是一个具有良好习惯的优秀程序员。― Kent Beck

Flask简介

Flask是一个Python的一个 Web 框架,负责管理应用所需的所有路由,这样你就不用自己编写相关代码了!

在浏览器中输入 “http://www.baidu.com” – 你的计算机就会向存储百度网站的另一台机器(比如服务器 server)发送一个请求,然后百度服务器会向你发送浏览器渲染网站所需要的文件。百度的计算机被称为服务器,因为它在你发出请求后,向你提供了发送文件的“服务”。

Web 地址的 HTTP 是 Hypter-Text Transfer Protocol 的缩写,意为超文本传输协议。HTTP 定义了通过互联网发送和接收消息的标准方式。

当你在浏览器中按下回车键时,你的计算机就在传达这样的信息“请给我 www.baidu.com 网页的所有文件”。这条信息使用 HTTP 管理的语法发送到服务器,然后服务器也通过协议将文件发送回来。

服务器上需要有一些软件可以解释这些 HTTP 请求并发送正确的文件,这就是像 Flask 这样的 Web 框架发挥作用的地方。框架会将代码抽象,完成接收请求、解释请求并发送正确的文件。

为什么选择Flask?

  • 首先,最重要的原因是 Flask 是用 Python 编写的,对于只会Python的来说不需要另外学习一门语言。
  • Flask 也是一个相对简单的框架,因此适合制作小型的 Web 应用。
  • 因为 Flask 是用 Python 编写的,所以你可以将 Flask 与任何其他的 Python 库一起使用,包括 pandas、numpy 和 scikit-learn。在本项目中,将使用pandas库对数据进行预处理。

安装Flask

可直接使用pip和conda两种方式安装Flask包

pip install flask
conda install flask

最简单的Flask实例

首先我们将使用Flask实现一个最简单的网页App,创建一个名为routes.py文件,写入如下代码

import flask from Flask #从flask库中导入Flask类

app = Flask(__name__) #定义app实例
@app.route('/') #使用app.route装饰器
def hello(): 
    return "Hello World!"

if __name__ == "__main__":
    app.run(host='0.0.0.0',port=5000) #启动服务

app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递__name__flask.helpers.get_root_path函数通过传入这个名字确定程序的根目录,以便获得静态文件和模板文件的目录

使用app.route装饰器会将URL和执行的视图函数的关系保存到app.url_map属性上,处理URL和视图函数的关系的程序就是路由,这里的视图函数就是hello,那么什么是装饰器呢?app.route的作用是什么呢

以下简要论述Python中装饰器的作用1

def decorator_factory(enter_message, exit_message):
    def simple_decorator(f):
        def wrapper():
            print(enter_message)
            f()
            print(exit_message)
        return wrapper
    return simple_decorator

def goal():
    print('I need to be executed!')
  • 外层decorator factory函数传入两个字符串,没有返回值
  • 内层simple decorator函数传入一个函数,并返回自身
  • 最内层wrapper函数没有传入值,将分别执行两个print函数以及上一层函数传入的f,并且返回自身

在不使用装饰器之前,若要得到打印值

outer = decorator_factory('start','end')
outer
<function __main__.decorator_factory.<locals>.simple_decorator(f)>

因为执行decorator_factory得到的是simple_decorator,故需要继续传入函数

inner = outer(goal)
inner
<function __main__.decorator_factory.<locals>.simple_decorator.<locals>.wrapper()>

发现得到的inner依旧是函数,所以需要执行此函数才能得到最终的结果

inner()
start
I need to be executed!
end

由此才得到了最终的结果,而如果使用装饰器@,则可以省去这些繁琐的步骤

@decorator_factory('start','end')
def func():
    print('I need to be executed!')
func()
start
I need to be executed!
end

以下简要论述app.route的作用:
在了解了装饰器的基本作用后,让我们将目光回到之前创建的app实例,它具体的作用是什么?为了理解它的基本作用,我们先创建一个自己的类,NotFlask

class NotFlask():
    def route(self, route_str):
        def decorator(f):
            return f

        return decorator

app = NotFlask()

@app.route("/")
def hello():
    return "Hello World!"

可能会发现,这个装饰器和上一个定义的装饰器的主要区别在于,这个装饰器本身没有任何作用,只是为了让我们可以访问这个函数,事实上,当我们执行hello函数,将直接返回hello函数的内容

hello()
Hello World!

所以,我们接下去要做的是利用decorator函数,存储我们的路由地址,为了实现这一目的,我们将定义一个字典,用来储存地址信息

class NotFlask():
    def __init__(self):
        self.routes = {}

    def route(self, route_str):
        def decorator(f):
            self.routes[route_str] = f
            return f

        return decorator

app = NotFlask()

@app.route("/")
def hello():
    return "Hello World!"

当我们每次访问route函数时,routes字典会添加路由地址,并将传入的f函数存到对应的字典值中,所以,当我们想访问routes中的地址时,得到的就是传入函数

app.routes['/']()
Hello World!

我们已实现了通过访问decorator函数存储路由地址的目的,但是,如果没有办法访问字典中路由地址对应的传入函数该怎么办?为此,我们在NotFlask类中添加一个server函数,来检查传入函数是否可以访问

class NotFlask():
    def __init__(self):
        self.routes = {}

    def route(self, route_str):
        def decorator(f):
            self.routes[route_str] = f
            return f
        return decorator

    def serve(self, path):
        view_function = self.routes.get(path) #查字典
        if view_function:
            return view_function()
        else:
            raise ValueError('Route "{}"" has not been registered'.format(path))

app = NotFlask()

@app.route("/")
def hello():
    return "Hello World!"
print(app.serve('/'))
Hello World!

在简要解释了app.route的作用后,让我们再看一看flask库中route的具体decorator,其中rule是路由地址,比如"/",通过add_url_rule函数添加到url_map

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

最后执行app.run就可以启动服务了。默认Flask只监听虚拟机的本地127.0.0.1这个地址,端口为5000,0.0.0.0表示监听所有地址,这样就可以在本机访问了。当我们访问“http://127.0.0.1:5000/”,通过app.url_map找到注册的“/”这个URL模式,就找到了对应的hello_world函数执行,返回“hello world!”,状态码为200。如果访问一个不存在的路径,如访问“http://127.0.0.1:5000/a”,Flask找不到对应的模式,就会向浏览器返回“Not Found”,状态码为404

Flask 访问HTML文件

在上一个实例中,我们实现了在网页中成功显示”Hello Wordl !”,但实际上,要做出一个完整的网页App,我们还需要掌握前端知识如html、css以及javascript等。接下去我们将创建不同的路由地址,并且访问对应的html文件

我们将创建一些需要的文件夹以及文件,新建WebApp并在其中创建如下文件/文件夹
在这里插入图片描述
execute.py文件是最终执行的文件,demo文件夹中创建templates文件夹、__init__.py文件和routes.pyroutes.py是创建路由地址并访问html文件的程序,在templates文件夹中创建homepage.html, subpage1.htmlsubpage2.html网页文件

首先我们将在__init__.py写入代码,当访问demo文件夹时,会自动先执行__init__.py中的内容,我们在__init__.py文件中

  • 从flask库导入Flask类
  • 定义Flask实例app
  • 导入routes库
from flask import Flask

app = Flask(__name__)

from demo import routes

其次我们来看看routes.py文件中该实现什么功能,我们从flask库中导入了render_template函数,flask框架通过render_template函数实现模版的渲染,可以简单将此函数的功能视为找到html文件并成功显示在页面中,需要注意的是,render_template函数会默认寻找templates文件夹中的html文件,故文件夹名必须为templates并与routes.py文件在同一路径下。此文件定义了三个路由地址,分别对应三个不同的html文件(路由地址名无需与文件名相同,此处是为了方便)

from demo import app #将首先执行__init__.py中app=Flask(__name__)
from flask import render_template 

@app.route('/')
def homepage():
    return render_template('homepage.html')

@app.route('/subpage1')
def subpage1():
    return render_template('subpage1.html')

@app.route('/subpage2')
def subpage2():
    return render_template('subpage2.html')

homepage.html, subpage1.html, subpage2.html中的模版如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>homepage</title>
</head>
<body>
This is homepage
</body>
</html>

最后,让我们回到WebApp中的execute.py文件,执行app.run函数

from demo import app

app.run(host='0.0.0.0', port=5000, debug=True)

在终端执行python execute.py命令并可成功访问本地地址

  • 0.0.0.0:5000/ 返回:This is homepage
  • 0.0.0.0:5000/subpage1 返回:This is subpage1
  • 0.0.0.0:5000/subpage2 返回:This is subpage2

总结

在此篇文章中,我们介绍了什么是Flask,为什么要用Flask框架,并且实现了一个最简单的网页app和创建不同路由地址访问相应的html文件。

在Python Flask+Pandas+Plotly实战(二)中,将使用World Bank的数据通过pandas库进行数据清洗之后,显示在网页中


  1. python装饰器 ↩︎


版权声明:本文为weixin_45681788原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。