day04
内容概要
- 请求上下文分析(源码request原理)
- wtforms(了解)
补充
导出项目依赖
之前 pip freeze > requirements.txt把当前解释器环境下的所有第三方依赖都导出来
使用第三方模块,更精确的导出依赖pipreqs
第一步:安装 pip install pipreqs
第二步:使用命令,导出项目依赖pipreqs ./
win由于编码问题可能会出错:pipreqs ./ --encoding=utf8


mac,linx没有问题
第三步:就会在项目根路径下生成:requirements.txt
函数和方法
只要会自动传值,就是方法,函数,有几个值就要传几个值,否则报错
函数就是普通函数,有几个参数就要传几个参数
方法:绑定给对象的方法,绑定给类的方法,绑定给谁的,有谁来调用,会自动把自身传入
类的绑定方法,对象可以来调,会自动把类传入
对象的绑定方法:类可以来调用,但是它就是普通函数。有几个参数就需要传几个参数
MethodType检查一个对象, 是不是方法
FunctionType检查一个对象,是不是函数
isinstance 判断 一个对象, 是不是一个类的对象
issubclass 判读一个类,是不是另一个类的子类
from types import MethodType, FunctionType
# isinstance
# issubclass
class A:
pass
class B(A):
pass
obj = A()
obj1 = B()
# print(isinstance(obj, A)) # True
# print(isinstance(obj1, A)) # True
# print(type(obj) == A) # True
# print(type(obj1) == A) # False
# class C:
# pass
#
#
# print(issubclass(B, A)) # True
# print(issubclass(A, A)) # True
# print(issubclass(C, A)) # False
判断函数和方法
from types import MethodType, FunctionType
class A:
def aa(self):
pass
@classmethod
def bb(cls):
pass
@staticmethod
def cc():
pass
def add():
pass
# 判断对象调用 aa, bb, cc,
# obj = A()
# print(isinstance(obj.aa, MethodType)) # True 对象调用一个绑定给对象的方法, 该方法就是方法
# print(isinstance(obj.bb, MethodType)) # True 对象调用一个绑定给类的方法, 该方法就是方法
# print(isinstance(obj.cc, MethodType)) # False 对象调用一个静态方法, 该方法是 普通函数
#
# print(isinstance(obj.aa, FunctionType))
# print(isinstance(obj.bb, FunctionType))
# print(isinstance(obj.cc, FunctionType))
# 判断类调用 aa, bb, cc,
# print(isinstance(A.aa, MethodType)) # False 类调用一个绑定给对象的方法, 该方法变成了普通函数
# print(isinstance(A.bb, MethodType)) # True 类调用一个绑定给类的方法, 该方法就是方法
# print(isinstance(A.cc, MethodType)) # False 类调用一个静态方法, 该方法是 普通函数
#
# print(isinstance(A.aa, FunctionType))
# print(isinstance(A.bb, FunctionType))
# print(isinstance(A.cc, FunctionType))
print(isinstance(add, FunctionType)) # True
总结:只要会自动传值,就是方法,函数,有几个值就要传几个值,否则报错
threading.local对象
local对象
并发编程时,多个线程操作同一个变量,会出现并发安全问题,咱们需要加锁
使用local对象,多线程并发操作时,不需要加锁,不会出现数据错乱threading.local
其他语言也有这个东西ThreadLocal,java中面试会被经常问到,python没人问
本质原理:
多个线程修改同一个数据,复制多份变量每个线程用,为每个线程开辟一块空间进行数据存储
每个线程都有自己那部分数据

但是我睡2s后
# import time
# from threading import Thread, get_ident
# lqz = ""
# def task(i):
# global lqz
# lqz = i
# print(lqz,"前")
# time.sleep(2)
# print("线程%s" % get_ident(), lqz)
# if __name__ == '__main__':
# for i in range(10):
# Thread(target=task, args=(i,)).start()

使用local方法
# import time
# from threading import Thread, get_ident, local
# l = local()
# def task(i):
# global lqz
# l.a = i
# time.sleep(2)
# print("线程%s" % get_ident(), l.a)
# if __name__ == '__main__':
# for i in range(10):
# Thread(target=task, args=(i,)).start()

多个线程修改同一个数据,复制多份变量每个线程用,为每个线程开辟一块空间进行数据存储
每个线程都有自己那部分数据
偏函数
def add(a, b, c):
return a + b + c
# add(2) # 直接报错
# 现在只有一个参数, 后面的俩参数,需要过一会才知道
# 借助与偏函数,先提前给它把第一个参数传入,后面知道了
# 后面俩参数,在传后面俩
add = partial(add, 2) # 先传一个参数
print(add(3, 4))

flask整个生命执行流程(1.1.4版本为例)
储备









我们回到 Flask的 wsgi_app方法中继续往下走






我们在回到RequestContext的push方法中

{"id":{"stack":[app_cotext,request_context]}}

wtforms
django有forms组件
- 生成前端模板
- 校验数据
- 渲染错误信息
flask中使用第三方的wtforms实现像django的forms一样的功能
- 导入,定义一个类,继承forms
- 模板中,for循环生成模板
- 视图函数中,使用form检验数据
py
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets
app = Flask(__name__, template_folder="templates")
app.debug = True
class LoginForm(Form):
# 字段
name = simple.StringField(
label="用户名",
validators=[
validators.DataRequired(message="用户名不能为空"),
validators.Length(min=6, max=18, message="用户名长度必须大于%(min)d且小于%(max)d"),
],
widget=widgets.TextInput(), # 页面上显示的插件
render_kw={"class": 'form-control'}
)
pwd = simple.PasswordField(
label="密码",
validators=[
validators.DataRequired(message="密码不能为空"),
validators.Length(min=6, max=18, message="密码长度必须大于%(min)d且小于%(max)d"),
validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}",
message="密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符")
],
widget=widgets.PasswordInput(), # 页面上显示的插件
render_kw={"class": 'form-control'}
)
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "GET":
form = LoginForm()
return render_template('login.html', form=form)
form = LoginForm(formdata=request.form)
if form.validate():
print("用户提交数据通过格式校验的值为:", form.data)
return render_template("login.html", form=form)
if __name__ == '__main__':
app.run()
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<p>{{form.name.label}}: {{form.name}} {{form.name.errors[0] }}</p>
<p>{{form.pwd.label}} {{form.pwd}} {{form.pwd.errors[0] }}</p>
<input type="submit" value="提交">
</form>
</body>
</html>


去除前端的校验



浙公网安备 33010602011771号