首先,推荐一个便宜的云主机,感觉比阿里便宜,新用户一年68元,滴滴云
附上活动链接:https://i.didiyun.com/2d7Jy4Nzle8

Flask的最小应用程序如下:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello World'
    
if __name__ == '__main__':
    app.run()

app.run()

Flask的类从flask包中引入后,直接制造app实例,使用app实例执行run方法。
所以先来看看Flask类中的_init__()和run()方法

def __init__( 
# 这里用的比较多的是,static_folder,static_url_path静态目录的指定,实例中都是默认参数
    self,
    import_name,
    static_url_path=None,
    static_folder="static",
    static_host=None,
    host_matching=False,
    subdomain_matching=False,   
    template_folder="templates",    
    instance_path=None,    
    instance_relative_config=False,    
    root_path=None,
def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
    try:
        run_simple(host, port, self, **options)
    finally:
        self._got_first_request = False

run方法中省略调试相关的代码,关键执行代码是run_simple方法,带入默认的host和port以及对象,host为127.0.0.1,port为5000。那么就来分析run_simple()

run_simple()

run_simple方法来自werkzeug中的serving.py。

def run_simple(
    hostname,
    port,
    application
):
    def inner():
        try:
            fd = int(os.environ["WERKZEUG_SERVER_FD"])
        except (LookupError, ValueError):
            fd = None
        srv = make_server(
            hostname,
            port,
            application,
            threaded,
            processes,
            request_handler,
            passthrough_errors,
            ssl_context,
            fd=fd,
        )
        if fd is None:
            log_startup(srv.socket)
        srv.serve_forever()
    inner()

run_simple()主要是执行了inner(),inner中初始化srv实例后执行srv.serve_forever()方法。先看make_server()方法,根据进程和线程使用不同的类进行初始化,且这些类都继承了BaseWSGIServer。

def make_server(    
    host=None, 
    port=None, 
    app=None, 
    threaded=False,
    processes=1, 
    request_handler=None,
    passthrough_errors=False,
    ssl_context=None,    fd=None,): 
    if threaded and processes > 1:
        raise ValueError("cannot have a multithreaded and multi process server.")
    elif threaded:       
        return ThreadedWSGIServer(省略 )   
    elif processes > 1:
        return ForkingWSGIServer(省略 )
    else: 
        return BaseWSGIServer(省略 )

这里以BaseWSGIServer为例进行分析。BaseWSGIServer继承HTTPServer,这里带入的参数除了host,port还有handler,sWSGIRequestHandler,WSGIRequestHandler继承BaseHTTPRequestHandler。主要是为了实现http的数据请求和发送。

class BaseWSGIServer(HTTPServer, object):    """Simple single-threaded, single-process WSGI server."""    
    multithread = False    
    multiprocess = False
    def __init__(    
        self, 
        host,
        port,
        app,
        handler=None, 
        passthrough_errors=False,
        ssl_context=None, 
        fd=None,):
        if handler is None: 
            handler = WSGIRequestHandler

先看一下执行函数,serve_forever,执行的是 HTTPServer.serve_forever()

def serve_forever(self): 
    self.shutdown_signal = False
    try:       
        HTTPServer.serve_forever(self)
    except KeyboardInterrupt: 
        pass
    finally:
        self.server_close()

为了更好的说明,把WSGIRequestHandler和BaseWSGIServer继承过来,单独运行获得http的响应。

from werkzeug.serving import WSGIRequestHandler,BaseWSGIServer

class New_Handler(WSGIRequestHandler):
    page = '''\
               <html>
               <body>
               <p>hello</p>
               </body>
               </html>
               '''

    def do_GET(self):
        current_path = self.path
        # self.send_error(415,'your url is %s' % current_path)
        self.send_response(200)
        self.send_header("Content-Type", "text/html")
        self.send_header("Content-Length", 100)
        self.end_headers()
        self.wfile.write(self.page.encode('utf-8'))

tcp_server = BaseWSGIServer(host="127.0.0.1",port=5000,app=None,handler=New_Handler)

if __name__ == "__main__":
    tcp_server.serve_forever()

既然http的请求响应入口已经找到了,那么就来看看请求路由的处理,所以要研究装饰器@app.route(‘/’),来看看Flask中路由处理思路。
装饰器如下:

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

# 路由装饰器的使用
@app.route('/')
def hello_world():
    return "hello_world"

以简单根目录请求为例,通过装饰器可以看出,首先执行self.add_url_rule(rule, endpoint, f, **options),然后再执行实例方法hello_world()。

版权声明:本文为vpandaxjl原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/vpandaxjl/p/12442672.html