ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【2】Flask Werkzeug简介

2020-07-11 13:36:32  阅读:438  来源: 互联网

标签:__ run Flask 简介 app flask Werkzeug self


Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库。 werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等 。

代码示例:

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)

flask正是依赖于这个werkzeug模块,由wekzeug模块实现了socket服务端的功能,hello必然是加括号运行了,才会执行hello里面的代码,而在flask中app.run()会调用run_simple(host, port, self, **options)把上面代码例子的hello替换成了self也就是app。app()会触发Flask类的__call__方法。

所以flask程序的入口就在__call__方法中,而__call__方法返回self.wsgi_app(environ, start_response),所以整个程序的执行过程都在 self.wsgi_app(environ, start_response)中.

小节:

1 app.run() 调用 werkzeug.serving的run_simple(host, port, self, **options)
2 self()等价于app(), app()调用Flask类的__call__方法
3 Flask类的__call__方法返回了 self.wsgi_app(environ, start_response)
4 flask程序的执行过程都在 self.wsgi_app(environ, start_response)中

app.run()具体源码:

def run(self, host=None, port=None, debug=None,
            load_dotenv=True, **options):
       
    	 ...
        
         _host ='127.0.0.1'
         _port = 5000
        
         ...
            
         host = host or sn_host or _host
         port = int(port or sn_port or _port)
            
         ...
    
         from werkzeug.serving import run_simple

            try:
                run_simple(host, port, self, **options)
            finally:
                # reset the first request information if the development server
                # reset normally.  This makes it possible to restart the server
                # without reloader and that stuff from an interactive shell.
                self._got_first_request = False
    ...
    
    def __call__(self, environ, start_response):
        """The WSGI server calls the Flask application object as the
        WSGI application. This calls :meth:`wsgi_app` which can be
        wrapped to applying middleware."""
        return self.wsgi_app(environ, start_response)
    ...
    
    def wsgi_app(self, environ, start_response):
        
        ctx = self.request_context(environ)
        error = None
        try:
            try:
                ctx.push()
                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)
   ...

关键词

  • Werkzeug是一个WSGI工具包,本质上是一个socket服务端。
  • flask基于Werkzeug,flask只保留了web开发的核心功能。
  • flask的执行过程都在def wsgi_app(self, environ, start_response):

4.2.3 运行项目

运行起来我们的flask项目,也可以在app.py直接右键run启动项目

图(1)

然后访问http://127.0.0.1:5000/

图(2)

!强调以后我们创建flask项目不要用pycharm自带的flask快捷方式创建,上边的快捷创建方式是便于讲解和理解,真实的生产环境更推荐直接创建一个空的python项目

4.2.4 详解DEBUG模式

4.3.4.1 DEBUG模式解决了两个问题。
  1. flask代码中如果出现了异常,在浏览器中不会提示具体的错误信息,开启debug模式后会把具体的错误信息发送到浏览器上。

  2. flask代码如果被修改了,必须要重启项目修改的代码才会有效,开启debug模式后修改了代码只要ctrl+s我们的flask项目就会自动重新加载,不需要手动加载整个网站。

    例1:

    此案例明显出现了一个数组越界的问题

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/')
    def hello():
        a = [1,2,3,4]
        print(a[4])
    
        return "hello"
    
    if __name__ == '__main__':
        app.run()
    

图(3)

如图3只提示了服务器内部错误,并没有提示具体的错误原因

好我们为app.run()添加参数改写为app.run(debug=True)

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    a = [1,2,3,4]
    print(a[4])

    return "hello"

if __name__ == '__main__':
    app.run(debug=True)

图(4)

看到了具体的报错信息 IndexError: list index out of range

并且每次修改代码的时候按下ctrl+s保存一下都会自动重新加载flask项目代码

4.2.4.2 四种开启DEBUG的方式

第一种

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    a = [1,2,3,4]
    print(a[4])
    return "hello"

if __name__ == '__main__':
    app.run(debug=True)  # 设置

第二种

from flask import Flask
app = Flask(__name__)
app.debug = True  # 设置

@app.route('/')
def hello():
    a = [1,2,3,4]
    print(a[4])
    return "hello"

if __name__ == '__main__':
    app.run()

第三种

from flask import Flask
app = Flask(__name__)
app.config.update(DEBUG=True)  # 设置

@app.route('/')
def hello():
    a = [1,2,3,4]
    print(a[4])
    return "hello"

if __name__ == '__main__':
    app.run()

第四种

需要在app.py所在的目录里 再创建一个config.py,随着学习会越来越多的用到这个配置文件,来配置flask`项目,注意配置的信息一般为大写。

config.py
DEBUG = True

app.py
from flask import Flask
import config  # 导入
app = Flask(__name__)

app.config.from_object(config)  # 设置

@app.route('/')
def hello():
    a = [1,2,3,4]
    print(a[4])
    return "hello"

if __name__ == '__main__':
    app.run()

app.config 本质上继承的字典,是字典的子类的一个对象 如图(5)

图(5)

4.2.4.3 DEBUG的PIN码可以在浏览器端调试代码使用(了解)
* Debugger PIN: 648-906-962

图(6)

可以支持在网页端调试

图(7)

原文:https://www.cnblogs.com/xiaoyuanqujing/articles/11643999.html

标签:__,run,Flask,简介,app,flask,Werkzeug,self
来源: https://www.cnblogs.com/remixnameless/p/13283296.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有