【flask】三种路由和各自的比较配置文件所有的字母必须大写if __name__的作用核心对象循环引用的几种解决方式--难Flask的经典错误上下文管理器

news2024/11/25 21:40:49

三种路由

方法1:装饰器 python C#, java 都可以用这种方式

from flask import Flask
app = Flask(__name__)

@app.route('/hello')
def hello():
	return 'Hello world!'

app.run(debug=True)

方法2: 注册路由 php python

from flask import Flask
app = Flask(__name__)

//@app.route('/hello')
def hello():
	return 'Hello world!'

app.add_url_rule('/hello', view_func=hello)

app.run(debug=True)

方法3:python 特有的规则

from flask.views import View, MethodView
from flask import Flask, render_template, request

app = Flask(__name__)


class MyView(MethodView):
    def get(self):
        return render_template('index.html')

    def post(self):
        username = request.form.get('username')
        password = request.form.get('password')
        if username == "gp" and password == "mypassword":
            return '密码正确'
        else:
            return '密码错误'


app.add_url_rule('/', endpoint='login', view_func=MyView.as_view('login'))


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000)

它的过程是通过View的as_view -> MethodView中的dispatch_request -> 具体的get、post等方法。

看一看flask 是如何实现的

class View:
   methods: t.Optional[t.List[str]] = None
   provide_automatic_options: t.Optional[bool] = None
   decorators: t.List[t.Callable] = []def dispatch_request(self) -> ResponseReturnValue:
       raise NotImplementedError()@classmethod
   def as_view(
       cls, name: str, *class_args: t.Any, **class_kwargs: t.Any
  ) -> t.Callable:
       def view(*args: t.Any, **kwargs: t.Any) -> ResponseReturnValue:
           self = view.view_class(*class_args, **class_kwargs)  # type: ignore
           return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)if cls.decorators:
           view.__name__ = name
           view.__module__ = cls.__module__
           for decorator in cls.decorators:
               view = decorator(view)
               
       view.view_class = cls  # type: ignore
       view.__name__ = name
       view.__doc__ = cls.__doc__
       view.__module__ = cls.__module__
       view.methods = cls.methods  # type: ignore
       view.provide_automatic_options = cls.provide_automatic_options  # type: ignore
       return view

实际上flask通过as_view方法,返回一个函数,这个函数就是我们需要绑定的视图函数,实现由类到函数的变化过程。

通过把cls绑定到view函数的view_class属性上面,实现view.view_class(*class_args, **class_kwargs)

来达到传递参数的目的,这正是python魅力之所在。就是用的闭包,或者装饰器了。和第一种方法类型,不过一个显示,一个隐式而已。

配置文件所有的字母必须大写

开发环境和测试环境以及生成环境的参数不同,那么如何区分这三个环境呢,if else 获取不一样的环境? 不是的,应该让三个环境相近,而使用配置文件将他们分开, 然后 设置 git ignore, 各自走各自的配置文件
在项目根路径下设置config.py

DEBUG=True

在面的启动文件

app = Flask(__name__)
# 加载配置项
app.config.from_object("config")
# 读取
app.config["DEBUG"]

注意flask 规定,只能用全大写,否则key error

if __name__的作用

是入口文件,增加了这个判断,能够确保入口文件里面的代码只在入口文件执行。

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000)

手动启动很好理解,因为他做了入口。
但是生产环境下是nginx+uwsgi,它是被uwsgi所加载的模块。入口文件变成了uwsgi,此时如果没有 if __name__的判断,会使web服务器启动两遍。一个是uwsgi的,一个是 开发中的python入口文件的,flask的内置服务器。

视图函数的return和普通函数的return有什么区别么?

有,不是一个简单的普通函数的return,是返回了一个response的响应对象。
视图函数,不会只返回类似 helloworld的字符串,
而是返回包含 status code 200,404, 301, content-type http headers,默认text/html
以及return的文本。

它等于

@app.route('/hello')
def hello():
	return 'helloworld'
@app.route('/hello')
def hello():
	return '<html></html>'
@app.route('/hello')
def hello():
	headers = {
		'content-type':'text/plain'
	}
	response = make_response('<html></html>',200)
	response.headers=headers
	return response 

最后一个会解析出html 因为他当成 text/plain 普通文本,而不是html文本了。

@app.route('/hello')
def hello():
	
	return '<html></html>', 301,headers

它等价于这个,flask 还是给返回了response对象。

解决核心对象重复引用

在flask中,将app的核心对象和注册路由写在同一个文件中是非常不好的体验

from flask import Flask
app = Flask(__name__)

@app.route('/hello')
def hello():
	return 'Hello world!'

app.run(debug=True)

只有1,2个路由是没问题的,可是,当有上百个路由的时候,而且开发者10个人同时在开发,大家都修改这一个入口文件,会造成很差的体验。
所以我们需要可以拆分路由,那么如何才能拆分呢?
可以add_url 的方式手动注册,但这种并不优雅。
我认为有两种比较好的
在这里插入图片描述
方式1: 保持核心对象app 只有一个,在util_help.py中定义一个函数,

from flask import Flask
def my_function():
    # 定义静态变量
    if not hasattr(my_function, "my_static_variable"):
        my_function.my_static_variable = Flask(__name__)
    
    return my_function.my_static_variable

谁用到app对象都去这里满拿,因为是定义了静态变量,所以,是独一份的,不会随着包引用构建多次. 注册路由是没问题的.

方式2: 通常情况会出现循环引用,因为入口文件会引入 app.web.book 文件, 而book文件又会去入口文件引入app, 造成两个app, 在book文件中的app对象,注册了路由函数,但不是入口文件的app对象.这个时候,蓝图就起作用了.

Flask的经典错误

working outside application context
AppContext, RequestContext, Flask与Request直接的关系.
应用上下文 对象 Flask
请求上下文 对象 Request
Flask AppContext
Request RequestContext
在这里插入图片描述
在这里插入图片描述
做上下文管理的源码!
用这两句把current_app 推进占
在这里插入图片描述
上下文管理的逻辑使用场景:
数据库:
1.连接数据库
2.执行sql
3.释放资源
解决方法1:
try

except

finall

解决方法2:
with 语句, 可以对比 whith open() as f:

文件读写:

try: 
	f = open(r"D:/t.txt")
	print(f.read())
finally:
	f.close()
with open(r"D:/t.txt") as f:
	print(f.read())

只要实现了__enter__ 和 __exit__方法就是上下文管理器.

class A:
	def __enter__(self):
	    a = 1
	def __exit__(self,exc_type, exc_value, tb):	
		if tb:
			print("process exception")
		else:
			print('no exception')
		b = 2
		return True
		# 或者返回 False, 代表异常还需要接着抛出去,
		# True 异常里面出来,外面不抛出异常
		# 什么都不返回 和False 的逻辑一致
		

with A() as obj_A:
     pass

现在的 obj_A 是 None
as 返回的不是上下文管理器,而是 enter方法返回的值.

with 语句包裹的变量值是有值的, 运行exit之后,就没值了.因为分别执行了 push 和pop,
push 就是把变量放进去, pop 就弹出来了.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/475869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端面经】JS-事件循环

什么是事件循环(Event Loop)? 众所周知, Javascript是一门单线程的语言, 单线程即同一时间只能做一件事, 但这并不意味着JavaScript在执行代码的过程中就会一直阻塞,而解决单线程不阻塞的这个机制就叫做事件循环(Event Loop), 也就是同步和异步的概念. 任务执行流程 在JS中…

PS滤镜插件-Nik Collection介绍

PS滤镜插件-Nik Collection介绍 什么是Nik CollectionNik Collection都包含什么&#xff1f; 什么是Nik Collection Nik Collection是一款PS滤镜插件套装&#xff0c;其包含了八款PS插件&#xff0c;功能涵盖修图、调色、降噪、胶片滤镜等方面。Nik Collection 作为很多摄影师…

redhat 安装oracle 11g

这里写目录标题 1、数据库下载和安装文档1.2、安装文档1.3、license种类解释&#xff08; XE版 标准本 个人版 企业版&#xff09;1.4、在安装完oracle后再创建数据库1.5、DBA的文档1.6、Automatic Storage Management Administrators Guide1.7、数据库备份恢复手册1.8、Overvi…

系统集成项目管理工程师 笔记(第15章 信息(文档)和配置管理)

文章目录 软件文档的分类&#xff08;1&#xff09;开发文档&#xff1a;描述开发过程 本身&#xff08;2&#xff09;产品文档&#xff1a;描述开发过程的 产物&#xff08;3&#xff09;管理文档&#xff1a;记录项目管理的信息 文档的质量可以分为四级&#xff08;1&#xf…

03_Uboot网络命令与MMC和文件操作命令

目录 网络操作命令 ping命令 nfs 命令 tftp 命令 EMMC和SD卡操作命令 mmc info命令 mmc rescan命令 mmc list 命令 mmc dev 命令 mmc part命令 mmc read 命令 mmc write 命令 mmc erase 命令 FAT 格式文件系统操作命令 fatinfo 命令 fatls 命令 fstype 命令 …

好的代码风格,如同书法,让你的代码更加漂亮

很多初学者的代码其实都不够“漂亮”&#xff0c;那是因为没有养成好的编码习惯。本篇博客以C语言为例&#xff0c;总结一些好习惯。其实&#xff0c;很多习惯都是肌肉记忆&#xff0c;举个例子&#xff1a;请你写一个程序&#xff0c;输入2个整数并输出它们的和。有些朋友可能…

java中的\t说明

阅读前请看一下&#xff1a;我是一个热衷于记录的人&#xff0c;每次写博客会反复研读&#xff0c;尽量不断提升博客质量。文章设置为仅粉丝可见&#xff0c;是因为写博客确实花了不少精力。希望互相进步谢谢&#xff01;&#xff01; 文章目录 阅读前请看一下&#xff1a;我是…

SQLIntegrityConstraintViolationException: Column ‘create_time‘ cannot be null

概述 在使用MySQL MyBatis时遇到的问题&#xff0c;记录一下。 问题 在测试环境里&#xff0c;往MySQL数据表里插入数据时报错&#xff1a;SQLIntegrityConstraintViolationException: Column create_time cannot be null 表结构字段定义&#xff1a; create_time dateti…

【Canvas入门】从零开始在Canvas上绘制简单的动画

这篇文章是观看HTML5 Canvas Tutorials for Beginners教程做的记录&#xff0c;所以代码和最后的效果比较相似&#xff0c;教程的内容主要关于这四个部分&#xff1a; 创建并设置尺寸添加元素让元素动起来与元素交互 设置Canvas的大小 获取到canvas并设置尺寸为当前窗口的大…

Lesson13 IP协议

IP: 提供一种能力,将数据从A主机送到B主机的能力,但不一定会成功 主机 : 配有 IP 地址 , 但是不进行路由控制的设备 ; 路由器: 即配有 IP 地址 , 又能进行路由控制 ; 节点 : 主机和路由器的统称; 协议头格式 如何封装和解包: 定长报头 自描述字段 如何交付(分用) : 8…

Linux驱动之input输入子系统

输入子系统用于实现Linux系统输入设备&#xff08;鼠标 键盘 触摸屏 游戏杆&#xff09;驱动的一种框架。Linux内核将其中的固定部分放入内核&#xff0c;驱动开发时只需要实现其中的不固定部分&#xff08;主要还是和硬件相关的部分&#xff09;&#xff0c;这和platform设备…

离散数学下--- 代数系统

代数系统 定义&#xff1a; 代数系统是用代数运算构造数学模型的方法。 • 通过构造手段生成&#xff0c;所以也称代数结构 • 代数运算&#xff1a;在集合上建立满足一定规则的运算系统 &#xff08;一&#xff09;二元运算 二元运算的定义 二元运算需要满足的两个条件&a…

【P1】Jmeter 准备工作

文章目录 一、Jmeter 介绍1.1、Jmeter 有什么样功能1.2、Jmeter 与 LoadRunner 比较1.3、常用性能测试工具1.4、性能测试工具如何选型1.5、学习 Jmeter 对 Java 编程的要求 二、Jmeter 软件安装2.1、官网介绍2.2、JDK 安装及环境配置2.3、Jmeter 三种模式2.4、主要配置介绍2.4.…

数据结构——二叉树层序遍历

数据结构——二叉树层序遍历 107. 二叉树的层序遍历 II199. 二叉树的右视图思路&#xff1a; 637. 二叉树的层平均值 107. 二叉树的层序遍历 II 107. 二叉树的层序遍历 II 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节…

心血管疾病预测--逻辑回归实现二分类

一、实现效果 实现心血管疾病的预测准确率70%以上 二、数据集介绍 数据共计70000条&#xff0c;其中心血管疾病患者人数为34979&#xff0c;未患病人数为35021。数据特征属性12个分别为如下所示:生理指标(性别、年龄、体重、身高等)、 医疗检测指标(血压、血糖、胆固醇水平等)…

【社区图书馆】PyTorch高级机器学习实战 读书感想

《PyTorch高级机器学习实战》十大特点 1. 深入全面的内容覆盖&#xff1a; 本书的内容深入而全面&#xff0c;涵盖了深度学习中的多个领域&#xff0c;包括自然语言处理、计算机视觉、强化学习等&#xff0c;并介绍了各种不同的神经网络结构和优化算法。 2. 理论和实践并重&am…

scratch拆礼物游戏 中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析2023年3月

目录 scratch拆礼物游戏 一、题目要求 1、准备工作 2、功能实现 二、案例分析 <

java spring 实现 下载hls(m3u8+ts)实时流并进行合并mp4和压缩

参考连接 链接: java下载m3u8视频&#xff0c;解密并合并ts&#xff08;三&#xff09; 链接: Java 下载 HLS (m3u8) 视频 首先需要了解什么是HLS 链接: HTTP Live Streaming (HLS) - 概念 链接: M3U8是什么 简单理解就是, m3u8文件存放着可供客户端播放TS 片段 简单一点…

吴恩达 Chatgpt prompt 工程--1.Guidelines

Setup #安装 !pip install openai#设置key !export OPENAI_API_KEYsk-... # or #import openai #openai.api_key "sk-..."import openai import osfrom dotenv import load_dotenv, find_dotenv _ load_dotenv(find_dotenv())openai.api_key os.getenv(OPENAI_A…

Graph Theory(图论)

一、图的定义 图是通过一组边相互连接的顶点的集合。 In this graph, V { A , B , C , D , E } E { AB , AC , BD , CD , DE } 二、图的类型 2.1 Finite Graph A graph consisting of finite number of vertices and edges is called as a finite graph. Null Graph Tri…