oldboy:s9day114

参考博客:https://www.cnblogs.com/wupeiqi/articles/7552008.html

一、Flask简介

1.安装Flask

pip install flask

Flask:

  - 短小精悍、可扩展性强的一个Web框架。

  - 依赖wsgi:werkzurg(安装Flask时,这些依赖也会被自动安装)

2.Werkzurg服务器

单独使用Werkzurg服务器:

from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple @Request.application
def run(request):
return Response('Hello World') if __name__ == '__main__':
run_simple('localhost', 4000, run)

3.实现简单页面请求

from flask import Flask

# 创建一个Flask实例,参数是为这个实例定义一个名字,一般以__name__来指定
app = Flask(__name__) # 利用装饰器,绑定路由
@app.route('/index')
def index():
return "HelloWorld" if __name__ == '__main__':
# 开始运行
app.run()

二、简单使用Flask

1.默认模板目录

Flask默认使用templates作为模板目录。当我们要返回html页面时,默认去该文件夹下找模板文件:

from flask import Flask, render_template

# 创建一个Flask实例,参数是为这个实例定义一个名字,一般以__name__来指定
app = Flask(__name__) @app.route('/login')
def login():
return render_template('login.html') if __name__ == '__main__':
# 开始运行
app.run()

2.修改模板目录

在Django中,我们是在setting配置文件中去修改。而在Flask中,我们可以以以下方式修改:

# 创建一个Flask实例,参数是为这个实例定义一个名字,一般以__name__来指定
app = Flask(__name__, template_folder='mytempfile')

我们查看一下Flask类的构造函数:

def __init__(
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
):

可以看到,默认的模板目录参数就是"templates"。

3.Flask接受POST请求、获取请求数据

在Flask中,默认只允许接收GET请求,如果我们先接收POST请求,则需要设置。

在视图函数中获取请求数据时,我们需要导入request模块,而不是通过参数传递request。这是个Django不同的地方。

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/login', methods=['GET', 'POST'])
def login():
# 这里的请求数据和Django中不一样,Flask是通过上下文来管理的,request不是参数,而是导入的模块
if request.method == 'GET':
pass if request.method == 'POST':
pass if __name__ == '__main__':
# 开始运行
app.run()

4.获取GET数据和POST数据

视图函数:

from flask import Flask, render_template, request, redirect

app = Flask(__name__)

@app.route('/login', methods=['GET', 'POST'])
def login():
# 这里的请求数据和Django中不一样,Flask是通过上下文来管理的,request不是参数,而是导入的模块
if request.method == 'GET':
# request.args对应django中的request.GET
# request.args.get('user)
return render_template('login.html')
if request.method == 'POST':
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'leokale' and pwd == '':
return redirect('/index')
else:
return render_template('login.html', error="用户名或密码错误")
# 也可以传多个值(使用字典),但和Django不一样的地方是要解包
# return render_template('login.html', **{"error": "用户名或密码错误"}) @app.route('/index')
def index():
return '<h2>欢迎登录</h2>' if __name__ == '__main__':
# 开始运行
app.run()

注意几个和django框架不一样的地方:

1)需要在装饰器中传入methods参数,用来允许接收哪些请求

2)request.args和request.form分别对应django中的request.GET和request.POST

3)redirect跳转和django基本一致

4)模板渲染回传给页面的参数,可以单独传一个,也可以使用字典拆包的形式传入多个(django中参数为字典)

对应html代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<h1>登录页面</h1>
<form method="POST">
<input type="text" name="user"/>
<input type="password" name="pwd"/>
<input type="submit" value="登录"/>{{error}}
 </form> </body> </html>

5.静态文件

Flask中静态文件默认放在static目录下,如果要修改,也是修改Flask实例化时的参数。

app = Flask(__name__,static_folder='mystatic')

只需要将目录名和这个参数值对应上即可。

但是注意,我们在html中写图片请求连接时使用的url默认是和static_folder一致的:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>INDEX</title>
</head>
<body>
<h2>欢迎访问</h2>
<img src="/mystatic/111.png">
</body>
</html>

但实际上,我们也可以通过一个参数来修改:

app = Flask(__name__, static_folder='mystatic', static_url_path='/vvvvv')

我们将其修改为'/vvvvv',此时html中也要修改为'/vvvvv':

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>INDEX</title>
</head>
<body>
<h2>欢迎访问</h2>
<img src="/vvvvv/111.png">
</body>
</html>

6.Flask中的session

from flask import Flask, render_template, request, redirect, session

app = Flask(__name__, static_folder='mystatic', static_url_path='/vvvvv')

@app.route('/login', methods=['GET', 'POST'])
def login():
# 这里的请求数据和Django中不一样,Flask是通过上下文来管理的,request不是参数,而是导入的模块
if request.method == 'GET':
# request.args对应django中的request.GET
# request.args.get('user)
return render_template('login.html')
if request.method == 'POST':
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'leokale' and pwd == '':
session['user'] = user
return redirect('/index')
else:
return render_template('login.html', error="用户名或密码错误")
# 也可以传多个值(使用字典),但和Django不一样的地方是要解包
# return render_template('login.html', **{"error": "用户名或密码错误"}) @app.route('/index')
def index():
user = session.get('user')
if not user:
return redirect('/login')
return render_template('index.html') if __name__ == '__main__':
# 开始运行
app.run()

Flask中session的使用和django很类似,但Flask中的session是导入的模块。

注意,Flask的session默认是保存在加密的cookie中的,可以参照django相关的介绍:https://www.cnblogs.com/leokale-zz/p/12082478.html

这里要使用加密的cookie,又需要设置MD5加盐中的盐,否则会报错:

RuntimeError: The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.
127.0.0.1 - - [20/Jan/2020 00:27:46] "POST /login HTTP/1.1" 500 -

我们需要在代码中加上加密设置:

app = Flask(__name__, static_folder='mystatic', static_url_path='/vvvvv')
app.secret_key = "sndjkfn" # MD5加密的盐

此时就可以使用加密cookie来保存session了。

三、Flask的配置文件

1.通过importlib导入指定模块

在setting.py文件中有如下代码:

class Foo(object):
DEBUG = True
TEST = False

我们如果在其他模块中通过importlib导入Foo类,获取其中的DEBUG和TEST的值:

import importlib

# 给定类所处模块
path = 'setting.Foo' # 分割path,获取模块名和类名
(m, c) = path.rsplit('.', maxsplit=1)
# 导入模块
m = importlib.import_module(m)
# 获取类
cls = getattr(m, c) # 遍历类中的属性,我们要获取的属性是大写的,所以使用isupper判断
for key in dir(cls):
if key.isupper():
print(key, getattr(cls, key))

这样,我们就使用importlib库动态的导入模块,并获取了其中的Foo类,以及其中的类属性。

Flask的配置文件也是通过这种方式来加载的(很多框架的配置文件都是通过这种方式加载)。

2.Flask默认的配置信息

Flask默认的配置信息:

from flask import Flask, request, render_template

app = Flask(__name__)
# app.config获取所有配置信息
print(app.config)
# 可以通过这种方式修改
app.config['DEBUG'] = True

app.config配置内容:

{
'ENV': 'development',
'DEBUG': False,
'TESTING': False,
'PROPAGATE_EXCEPTIONS': None,
'PRESERVE_CONTEXT_ON_EXCEPTION': None,
'SECRET_KEY': None,
'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days = 31), # 默认session的保存周期(对应加密cookie的过期时间)
'USE_X_SENDFILE': False,
'SERVER_NAME': None,
'APPLICATION_ROOT': '/',
'SESSION_COOKIE_NAME': 'session', # 加密session写到cookie中的key,默认叫session
'SESSION_COOKIE_DOMAIN': None,
'SESSION_COOKIE_PATH': None,
'SESSION_COOKIE_HTTPONLY': True,
'SESSION_COOKIE_SECURE': False,
'SESSION_COOKIE_SAMESITE': None,
'SESSION_REFRESH_EACH_REQUEST': True, # 是否在每次访问的时候刷新session过期时间(即从最后一次访问开始计算过期时间),如果为False,则过期时间时从设置session开始算
'MAX_CONTENT_LENGTH': None,
'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(seconds = 43200),
'TRAP_BAD_REQUEST_ERRORS': None,
'TRAP_HTTP_EXCEPTIONS': False,
'EXPLAIN_TEMPLATE_LOADING': False,
'PREFERRED_URL_SCHEME': 'http',
'JSON_AS_ASCII': True,
'JSON_SORT_KEYS': True,
'JSONIFY_PRETTYPRINT_REGULAR': False,
'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None,
'MAX_COOKIE_SIZE': 4093
}

3.使用自定义配置文件

使用以下方式为其指定一个自定义配置文件:

from flask import Flask, request, render_template

app = Flask(__name__)
# app.config获取DEBUG,默认为False
print(app.config['DEBUG'])
# 通过from_object绑定一个类作为配置对象,其中DEBUG为True
app.config.from_object("setting.Myconfig")
# 再次获取DEBUG,为True
print(app.config['DEBUG'])

这里使用setting模块中的Myconfig类作为其配置文件。from_object源码就是使用的1.中的方式对setting模块进行导入,然后获取Myconfig中的属性值。

setting模块中,我们还可以根据需求,使用多个类来区分不同场景下的配置:

class BaseConfig(object):
# DEV和PROD场景下,相同的配置
XXX = False # 开发环境下的配置
class DevConfig(BaseConfig):
DEBUG = True
TEST = True # 生产环境下的配置
class ProdConfig(BaseConfig):
DEBUG = False
TEST = False

在使用的时候,我们只需要根据场景切换即可:

# 开发环境使用DevConfig配置
app.config.from_object("setting.DevConfig") # 生产部署环境使用ProdConfig配置
app.config.from_object("setting.ProdConfig")

4.其他配置文件的使用

除了3.中所描述的,使用模块中的类来作为配置。还有以下几种方式:

1)from_pyfile

app.config.from_pyfile("setting.py")

例如:

# settings.py

DEBUG = True
TEST = False

2)from_envvar

app.config.from_envvar("FLASK_CONFIG_FILE")

例如在Linux下配置环境变量:

export FLASK_CONFIG_FILE='/path/to/config/file'

环境变量的值为python文件(不一定是.py结尾的文件,但内容要是 DEBUG = True这种Python代码格式)名称,内部调用from_pyfile方法。

3)from_json

app.config.from_json("json文件名称")

JSON文件名称,必须是json格式,因为内部会执行json.loads。

4)from_mapping

app.config.from_mapping({'DEBUG':True})

参数为一个字典。

四、Flask的路由系统

在Flask中,路由是通过装饰器加到每个视图函数的:

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/index', methods=['GET', 'POST'])
def hello_world():
if request.method == 'GET':
return render_template('index.html') if __name__ == '__main__':
app.run()

1.@app.route中的endpoint

@app.route中的endpoint参数,就相当于django中的name参数,用来反向生成URL。

from flask import Flask, request, render_template, url_for

app = Flask(__name__)

@app.route('/index', methods=['GET', 'POST'], endpoint='n1')
def hello_world():
print(url_for('n1')) # 打印/index
if request.method == 'GET':
return render_template('index.html') if __name__ == '__main__':
app.run()

其中的url_for相当于django中的reverse函数,用来利用endpoint反向生成url。

注意:如果我们不指定endpoint,则endpoint默认等于视图函数名,这里即"hello_world"。url_for("hello_world")即为"/index"。

2.动态路由

Flask的路由中,我们可以使用动态参数。

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/index/<int:nid>', methods=['GET', 'POST'])
def hello_world(nid):
print(nid)
if request.method == 'GET':
return render_template('index.html') if __name__ == '__main__':
app.run()

Flask是django使用动态路由的方式不同,在django中,动态路由是这样的:'/index/(?P<nid>\d+)'。

注意:<int:nid>中,int表示动态参数的类型,我们的视图函数接收的参数nid为整形,如果不写,则默认为字符串。

动态参数的类型除了有int以外,还有以下几种类型:

@app.route('/user/<username>')  # 字符串
@app.route('/post/<int:post_id>') # 整数
@app.route('/post/<float:post_id>') # 浮点数
@app.route('/post/<path:path>') # 路径类型
@app.route('/post/<uuid:uuid>') # UUID

在使用动态路由的时候,也可以使用方向生成url:

url_for("hello_world",nid=777)  # 生成/index/777

五、Flask的请求数据

在Flask中,视图函数没有request参数。Flask中的request是直接导入使用的(上下文管理)。

from flask import Flask, request

在视图函数中,可以直接使用request:

#例如请求: http://127.0.0.1:5000/index/2019-03?name=leo
#以下request的属性值为:
request.method # 请求类型
request.args # GET请求的数据
request.args.get('user')
request.form # POST请求的数据
request.form.get('user')
request.values
request.cookies # Cookie数据
request.headers
"""
Accept: text/html, application/xhtml+xml, image/jxr, */*
...
Connection: Keep-Alive
"""
request.path # 请求的url "/index/2019-12"
request.full_path # "/index/2019-12?name=leo" 包含query
request.script_root # ""
request.url # "http://127.0.0.1:5000/index/2019-12?name=leo"
request.base_url # "http://127.0.0.1:5000/index/2019-12"
request.url_root #"http://127.0.0.1:5000/"
request.host_url # "http://127.0.0.1:5000/"
request.host # "127.0.0.1:5000"
request.files
obj = request.files['file_name']
obj.save('/var/www/uploads/' + secure_filename(f.filename)) #上传文件

六、Flask的响应

1.Flask的几种常用响应

在Flask中,常用的响应方式有以下几种:

1)响应字符串

return "HelloWorld"  # 相当于django中的HttpResponse

2)响应json数据

from flask import jsonify
return jsonify({'k':'v'})
# 或 return json.dumps({'k':'v'})

3)响应渲染模板

from flask import render_template
return render_template('login.html') # 相当于django中的render

4)响应重定向

from flask import redirect
return redirect('/index')

2.设置响应头

在Flask中如何设置响应头,特别是响应字符串的时候,无法设置响应头。

from flask import make_response

# 使用响应对象来封装要返回的字符串
obj=make_response("hello world")
# obj=make_response(render_template('index.html')) # 设置响应头的字段xxx
obj.headers['xxx']=''
# 设置cookie
obj.set_cookie('key','value') # 返回obj
return obj

七、jinjia2模板语言

1.循环与字典取值

Jinjia2模板语言和django自带的模板语言很相似,但功能更加强大。语法比较接近于Python。

视图函数代码:

from flask import Flask, request, render_template

app = Flask(__name__)

USER_INFO = {
1: {'name': 'Leo', 'age': 32, 'gender': 'male'},
2: {'name': 'Jane', 'age': 33, 'gender': 'female'},
3: {'name': 'Jake', 'age': 12, 'gender': 'male'},
4: {'name': 'Alex', 'age': 45, 'gender': 'male'},
5: {'name': 'Lilei', 'age': 77, 'gender': 'female'}
} @app.route('/users', methods=['GET', 'POST'])
def user_list():
if request.method == 'GET':
return render_template('users.html', user_list=USER_INFO) if __name__ == '__main__':
app.run()

我们创建了一个字典,并返回给模板进行渲染。

html模板代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Users</title>
</head>
<body>
<h2>用户列表</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>名字</th>
<th>岁数</th>
<th>性别</th>
</tr>
</thead>
<tbody>
{% for k,v in user_list.items() %}
<tr>
<td>{{ k }}</td>
<td>{{ v.name }}</td>
<td>{{ v.age }}</td>
<td>{{ v.gender }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

可以看到,使用for循环的方法和django模板语言是一样的。

注意,user_list.items()这个括号一定要有,这和Python一样。

在取值的时候,使用{{ v.name }}这种形式可以获取字典中字段的值。在Jinjia2中,还可以使用{{ v.get('name','默认') }}以及{{ v['name'] }}的形式来取值,和Python基本一致。

2.数组取值

除了1.中所述的用法,这里补充一些用法:

{{ list.0 }}  # django模板语言风格取index为0的元素
{{ list[0] }} # python风格取index为0的元素

列表按索引取元素,两种风格都支持。

2)XSS问题

当数据为html标签时:

# data = "<input type='text' />"
{{ data }} # 显示字符串<input type='text' />
{{ data|safe }} # 显示input标签元素

Flask默认帮我们做了XSS,要返回标签格式的字符串,在模板语言中使用"|safe"。

当然,也可以在后端python中使用Markup来传递安全的标签字符串(类似django中的mark_safe):

from flask import Markup

Markup("<input type='text' />")  # 相当于django中的mark_safe

3.传递函数引用并调用

当我们在视图函数中传递给模板的参数是一个函数引用时:

例如:

def func(arg):
return arg**2 # 视图函数index
def index():
return render_template("index.html",func=func) #将func函数引用传递到模板

Jinjia2模板语言调用func:

{{ func(6) }}  # 显示36

虽然Jinjia2可以方便的调用函数(比django模板语言方便)。但是如果有多个页面都要调用这个函数,则每个对应的视图函数都要将该函数的引用传递给模板。则可以使用全局的模板函数(类似django中定义模板函数)。

4.全局模板函数

1)@app.template_global()装饰器

使用@app.template_global()装饰器,可以将自定义函数变为全局的模板函数,直接可以在模板语言中调用。

@app.template_global()
def my_add(a,b)
return a+b

在模板中调用:

{{ my_add(1,9) }}  # 显示10

2)@app.template_filter()装饰器

还有另一种装饰器@app.template_filter(),和template_global差不多,但是在模板语言中的调用方式不同:

{{ 1|my_add(9) }}  # 显示10

这两种方式在Jinjia2中其实效果差不多。

我们可以这样理解

  @app.template_global装饰的模板函数,对应的是django中 @register.simple_tag装饰的模板函数(但由于django模板语言在调用模板函数时,不是使用括号来包裹参数,所以无法作为if的条件)。

  @app.template_filter装饰的模板函数,对应的是django中 @register.filter装饰的模板函数(形式差不多)

由于Jinjia2中传参的方式和python很像,所以两种方式都可以作为if的条件。如下:

# tempalte_global装饰的my_add
{% if my_add(1,9) %}
{% endif %} # tempalte_filter装饰的my_add
{% if 1|my_add(9) %}
{% endif %}

5.定义宏(函数)

Jinjia2模板语言支持定义宏(其实就是定义函数):

<!-- 使用macro定义一个宏(相当于python的def定义函数) -->
{% macro my_func(name,type='text',value='') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}"/>
{% endmacro %}
<!-- macro定义的函数,默认是不执行的,需要手动调用 -->
{{ my_func('n1') }}
{{ my_func("n2",type="button",value='确定') }}

也就是说Jinjia2不仅可以支持在后台Flask中定义全局函数,还可以使用macro直接在模板中定义函数。

八、使用装饰器给视图函数添加验证功能

1.简单装饰器的问题

# 最简单的装饰器
def auth(func):
def inner(*args, **kwargs):
ret = func(*args, **kwargs)
return ret
return inner # index函数使用了auth装饰器
@auth
def index():
print('index') # index2函数没有使用auth装饰器
def index2():
print('index2') if __name__ == '__main__':
print(index.__name__) # 打印inner
print(index2.__name__) # 打印index2

可以看到,当一个函数使用了简单装饰器后,打印其函数名,编程了装饰器中的inner。

在这种情况下,会影响我们使用反向生成url的功能,即url_for(视图函数名)。

2.使用functools.wraps

# 导入functools中的wraps
from functools import wraps def auth(func):
# 使用wraps装饰器
@wraps(func)
def inner(*args, **kwargs):
ret = func(*args, **kwargs)
return ret return inner @auth
def index():
print('index') if __name__ == '__main__':
print(index.__name__) # 打印index

使用了functools的wraps装饰器,实际上运行index函数时,还是调用的是inner,但是wraps帮我们将index函数的元信息封装到了inner函数中。

3.使用auth装饰器实现登录验证

from flask import Flask, request, render_template, redirect, session, url_for

app = Flask(__name__)
# 使用密码盐(session默认保存在加密cookie中,必须设置密码盐)
app.secret_key = 'snjdkfnjsk' USER_INFO = {
1: {'name': 'Leo', 'age': 32, 'gender': 'male'},
2: {'name': 'Jane', 'age': 33, 'gender': 'female'},
3: {'name': 'Jake', 'age': 12, 'gender': 'male'},
4: {'name': 'Alex', 'age': 45, 'gender': 'male'},
5: {'name': 'Lilei', 'age': 77, 'gender': 'female'}
} from functools import wraps # 认证用户是否登录
def auth(func):
@wraps(func)
def inner(*args, **kwargs):
if not session.get('user'):
return redirect(url_for('login'))
ret = func(*args, **kwargs)
return ret return inner # 登录页面
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
user = request.form.get('username')
pwd = request.form.get('password')
# 用户名密码正确,则将用户名写到session中(默认保存在加密cookie中,默认cookie过期时间为31天)
if user == 'leokale' and pwd == '':
session['user'] = user
# 登录成功,跳转到users页面
return redirect('/users')
# 登录失败,返回login页面,并显示用户名或密码错误
return render_template('login.html', error='用户名或密码错误') # users页面,使用auth装饰器进行登录验证
@app.route('/users', methods=['GET', 'POST'])
@auth
def user_list():
if request.method == 'GET':
return render_template('users.html', user_list=USER_INFO) if __name__ == '__main__':
app.run()

1)实现验证装饰器,必须使用functools.wraps装饰器,保证视图函数名不变

2)在auth装饰器中实现验证登录功能(检查session中user是否存在)

3)将auth装饰器应用到需要验证的页面

[Python自学] Flask框架 (1) (Flask介绍、配置、Session、路由、请求和响应、Jinjia2模板语言、视图装饰器)的更多相关文章

  1. flask模板语言,装饰器,路由及配置

    1.模板语言jinja2 Flask中默认的模板语言是Jinja2 1.0 模板传参 from flask import Flask,render_template app = Flask(__nam ...

  2. Flask 模板语言,装饰器

      Jinja2模板语言 # -*- coding: utf-8 -*-   from flask import Flask, render_template, request, redirect,  ...

  3. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

  4. Python的Django框架中的URL配置与松耦合

    Python的Django框架中的URL配置与松耦合 用 python 处理一个文本时,想要删除其中中某一行,常规的思路是先把文件读入内存,在内存中修改后再写入源文件. 但如果要处理一个很大的文本,比 ...

  5. python 之 Django框架(Django框架简介、视图装饰器、request对象、Response对象)

    12.33 Django框架简介: MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器( ...

  6. flask之jinjia2模板语言

    flask_jinjia2.py ''' flask中的jinjia2模板语言(和django中模板类似): (1)模板变量{{ }} (2)模板标签{% %} ①for循环遍历 {% for foo ...

  7. Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)

    Python:高级主题之(属性取值和赋值过程.属性描述符.装饰器) 背景 学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同.还有词法作用域这个东西,这也是我学习任何一门语 ...

  8. ThinkPHP5.0框架开发--第6章 TP5.0 请求和响应

    ThinkPHP5.0框架开发--第6章 TP5.0 请求和响应 第6章 TP5.0 请求和响应 ===================================== 上次复习 1.新建控制器 ...

  9. Flask框架(一):介绍与环境搭建

    1.Flask介绍 Flask诞生于2010年,是Armin ronacher(人名)用 Python 语言基于 Werkzeug 工具箱编写的轻量级Web开发框架. Flask 本身相当于一个内核, ...

随机推荐

  1. 虚拟机ubuntu系统怎么添加 VMware tools

    首先弹出光盘 然后安装 点击安装VMware tools 然后进入光盘 打开VMware tools 文件夹 将解压文件拉到桌面上 打开桌面上的文件夹 不选中文件 然后键入下面的内容 输入密码 输入y ...

  2. 事务管理(ACID)

    目录 一.事务管理(ACID) 原子性(Atomicity) 一致性(Consistency) 持久性(Durability) 隔离性(Isolation) 二.事务隔离级别 脏读 不可复读 虚读(幻 ...

  3. Springboot | @RequestBody 接收到的参数对象属性为空

    背景 今天在调试项目的时候遇到一个坑,用Postman发送一个post请求,在Springboot项目使用@RequestBody接收时参数总是报不存在,但是多次检查postman上的请求格式以及项目 ...

  4. python中map()和dict()的用法

    map()用法 map()是python的内置函数,会根据提供的函数对指定序列做映射. 语法: map(func, iter, ...) 其中func为一个功能函数,iter表示可迭代参数序列.map ...

  5. django 发布会签到系统web开发

    引言 最近学习了虫师的发布会签到系统demo,结合自己所学django知识,对demo重新塑造了一下.也是为了练练手,巩固知识.现在就分享一下成果~ Django工作流 学习django web开发, ...

  6. JavaScript所有函数和内置方法

    Number isFiniter() 检测传入的的数值是否在无穷大和无穷小之间(有限数字或者是可转换成有限数字)返回true,否则返回false.NaN返回false. isFinite(Number ...

  7. python中常见的报错信息

    python中常见的报错信息 在运行程序时常会遇到报错提示,报错的信息会提示是哪个方向错的,从而帮助你定位问题: 搜集了一些python最重要的内建异常类名: AttributeError:属性错误, ...

  8. 快速理解YOLO目标检测

    YOLO(You Only Look Once)论文 近些年,R-CNN等基于深度学习目标检测方法,大大提高了检测精度和检测速度. 例如在Pascal VOC数据集上Faster R-CNN的mAP达 ...

  9. Codeforces 1138B Circus (构造方程+暴力)

    题意: 给你两个01串,要你选n/2个位置,使得选的位置在s1中"1"的数量等于未选的s2中"1"的数量 n<=5000,1s 思路: 设两个串中出现&q ...

  10. WebAPI 微信小程序的授权登录以及实现

    这个星期最开始 ,老大扔了2个任务过来,这个是其中之一.下面直接说步骤: 1.  查阅微信开发文档  https://developers.weixin.qq.com/miniprogram/dev/ ...