前情概要

   1.flask的基本使用

     - 配置

- 路由

- 视图

- 请求与响应相关

- 模板

   2.flask基于装饰器实现的路由

     - 基本操作

- functools

- 带参数的装饰器

     - 源码剖析

3.flask-基于源码剖析session&特殊装饰器原理

一.历史回顾

  1.装饰器原理

def wapper(func):
def inner(*args,**kwargs):
print("执行装饰器逻辑")
return func(*args,**kwargs)
return inner """
在程序执行从上到下加载,还未执行的时候 先执行如下两个步骤
1. 立即执行wapper函数,并将下面装饰的函数当做参数传递
2. 将wapper函数返回值获取,在index赋值
index = inner函数
"""
@wapper
def index():
print('函数内容') # 实际执行的 inner函数,inner函数内部调用原函数
index()

  2.functools

import functools
def wapper(func):
@functools.wraps(func)
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner @wapper
def index():
print('index') @wapper
def order():
print("order") """
默认不加functools会直接返回当前函数装饰器里inner的函数名字
"""
print(index.__name__)
print(order.__name__)
"""
返回值
index
order
"""

  3.面向对象封装

"""
面向对象封装
"""
#将一些变量封装到一个类里进行统一调用
class Foo(object):
def __init__(self,age,name):
self.age = age
self.name = name def get_info(self):
return self.name,self.age def __call__(self, *args, **kwargs):
return self.name class Bar(object):
def __init__(self,counter):
self.counter = counter
self.obj = Foo('18','guest') #这个也算是面向对象的组合,将用户封装到一个类里 b1 = Bar(1)
print(b1.obj.get_info())
print(b1.obj()) #对象加()执行对象所在类的__call__方法

  4.加()会有几种表现形式-函数,类,方法,对象

def f1():
print('f1') class F2(object):
pass class F3(object):
def __init__(self):
pass def ff3(self):
print('ff3') class F4(object):
def __init__(self):
pass def __call__(self, *args, **kwargs):
print('f4')
def func(arg):
"""
由于arg在函数中加括号,所以他只有4中表现形式:
- 函数
- 类
- 方法
- 对象
:param arg:
:return:
"""
arg() # 1. 函数,内部执行函数
func(f1)
# 2. 类,内部执行__init__方法
func(F2) # 3. 方法,obj.ff3,执行方法
obj1 = F3()
func(obj1.ff3) # F3.ff3(F3)类+方法的时候 方法就不是方法了而是函数 需要自行将self加进去 # 4. 对象
obj2 = F4()
func(obj2)

  5.函数和方法的区别

from types import MethodType,FunctionType
class F3(object):
def __init__(self):
pass def ff3(self):
print('ff3') # v1 = isinstance(F3.ff3,MethodType)
# v2 = isinstance(F3.ff3,FunctionType)
# print(v1,v2) # False,True obj = F3()
v1 = isinstance(obj.ff3,MethodType)
v2 = isinstance(obj.ff3,FunctionType)
print(v1,v2) # True False 

  

二、框架的本质

  1.基于socket实现

import socket
def main():
# 创建老师
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8000))
sock.listen(5) #队列长度 while True:
# 老师等待 用户请求的到来
connection, address = sock.accept()
# 获取发送的内容:x有没有女朋友?
# 获取发送的内容:xx 有没有女朋友?
# 获取发送的内容:xxx有没有女朋友?
# 获取发送的内容:xxxx有没有女朋友?
buf = connection.recv(1024) # 根据请求URL的不同:
# 回答:没有
connection.send(b"HTTP/1.1 200 OK\r\n\r\n")
connection.send(b"No No No")
# 关闭连接
connection.close()
if __name__ == '__main__':
main()

  2.flask依赖werkzeug,django依赖wsgiref

"""
from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple @Request.application
def hello(request):
return Response('Hello World!') if __name__ == '__main__':
# 当请求打来之后,自动执行:hello()
run_simple('localhost', 4000, hello)
""" from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple class Foo(object):
def __call__(self, *args, **kwargs):
return Response('Hello World!') if __name__ == '__main__':
# 当请求打来之后,自动执行:hello()
obj = Foo()
run_simple('localhost', 4000, obj)

  3.快速使用flask搭建web

from flask import Flask
# 1. 实例化Flask对象
app = Flask('xxxx') """
1. 执行 app.route('/index')并获取返回值 xx
2.
@xx
def index():
return 'Hello World'
3. 执行 index = xx(index)
本质:
{
'/index': index
}
"""
@app.route('/index')
def index():
return 'Hello World' if __name__ == '__main__':
app.run()

三、Flask快速使用

import functools
from flask import Flask,render_template,request,redirect,session app = Flask('xxxx',template_folder="templates")
app.secret_key = 'as923lrjks9d8fwlkxlduf'
def auth(func):
@functools.wraps(func) #为了添加路由的时候函数名为被装饰的函数名
def inner(*args,**kwargs):
user_info = session.get('user_info')
if not user_info:
return redirect('/login')
return func(*args,**kwargs)
return inner
"""
{
/order: inner函数, name: order
/index: inner函数, name: index
}
""" @app.route('/order',methods=['GET']) #认证的装饰器要放路由下面 先加载app.route
@auth
def order():
user_info = session.get('user_info')
if not user_info:
return redirect('/login') return render_template('index.html') @app.route('/index',methods=['GET'])
@auth
def index():
return render_template('index.html') @app.route('/login',methods=['GET','POST'])
def login():
if request.method == "GET":
return render_template('login.html')
else:
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'alex' and pwd == '123':
session['user_info'] = user
return redirect('/index')
# return render_template('login.html',msg = "用户名或密码错误",x = 123)
return render_template('login.html',**{'msg':'用户名或密码错误'}) @app.route('/logout',methods=['GET'])
def logout():
del session['user_info']
return redirect('/login')
if __name__ == '__main__':
app.run()

四、导入配置文件

  1.app.py

#app.py
from flask import Flask # 配置:模板/静态文件
app = Flask('xxxx',template_folder="templates")
# 配置:secret_key
app.secret_key = 'as923lrjks9d8fwlkxlduf' # 导入配置文件
app.config.from_object('settings.TestingConfig') @app.route('/index')
def index():
return "index" if __name__ == '__main__':
app.run()

 2.settings.py

class BaseConfig(object):
DEBUG = False
SESSION_REFRESH_EACH_REQUEST = True class ProConfig(BaseConfig):
pass class DevConfig(BaseConfig):
DEBUG = True class TestingConfig(BaseConfig):
DEBUG = True

flask配置文件详解:

flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:
{
'DEBUG': get_debug_flag(default=False), 是否开启Debug模式
'TESTING': False, 是否开启测试模式
'PROPAGATE_EXCEPTIONS': None,
'PRESERVE_CONTEXT_ON_EXCEPTION': None,
'SECRET_KEY': None,
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
'USE_X_SENDFILE': False,
'LOGGER_NAME': None,
'LOGGER_HANDLER_POLICY': 'always',
'SERVER_NAME': None,
'APPLICATION_ROOT': None,
'SESSION_COOKIE_NAME': 'session',
'SESSION_COOKIE_DOMAIN': None,
'SESSION_COOKIE_PATH': None,
'SESSION_COOKIE_HTTPONLY': True,
'SESSION_COOKIE_SECURE': False,
'SESSION_REFRESH_EACH_REQUEST': True,
'MAX_CONTENT_LENGTH': None,
'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
'TRAP_BAD_REQUEST_ERRORS': False,
'TRAP_HTTP_EXCEPTIONS': False,
'EXPLAIN_TEMPLATE_LOADING': False,
'PREFERRED_URL_SCHEME': 'http',
'JSON_AS_ASCII': True,
'JSON_SORT_KEYS': True,
'JSONIFY_PRETTYPRINT_REGULAR': True,
'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None,
} 方式一:
app.config['DEBUG'] = True PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...) 方式二:
app.config.from_pyfile("python文件名称")
如:
settings.py
DEBUG = True app.config.from_pyfile("settings.py") app.config.from_envvar("环境变量名称")
环境变量的值为python文件名称名称,内部调用from_pyfile方法 app.config.from_json("json文件名称")
JSON文件名称,必须是json格式,因为内部会执行json.loads app.config.from_mapping({'DEBUG':True})
字典格式 app.config.from_object("python类或类的路径") app.config.from_object('pro_flask.settings.TestingConfig') settings.py class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:' class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo' class DevelopmentConfig(Config):
DEBUG = True class TestingConfig(Config):
TESTING = True PS: 从sys.path中已经存在路径开始写 PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录

  

五、给字符串路径自动找到指定类并执行

  importlib + 反射

import settings
import importlib
def send_notify():
for path in settings.NOTIFY_LIST:
# 'notify.email.Email',
# 'notify.msg.Msg',
module_path,cls_name = path.rsplit('.',maxsplit=1) #右排序 取一个
# m = importlib.import_module("notify.email") # import notify.email
m = importlib.import_module(module_path)
cls = getattr(m,cls_name)
obj = cls()
obj.send() """
settings.py
NOTIFY_LIST = [
'notify.email.Email',
'notify.wechat.Wechat',
'notify.msg.Msg',
""" """
run.py
from notify import send_notify def run():
send_notify() if __name__ == '__main__':
run()
""" 

六、路由系统  

  1.cbv与fbv的使用方法:fbv可以种app.route的方法添加

#fbv可以用装饰器
@app.route('/index')
def index():
return "index" def order():
return 'Order'
app.add_url_rule('/order', None, order) class TestView(views.View):
methods = ['GET']
def dispatch_request(self):
return 'test!' app.add_url_rule('/test', view_func=TestView.as_view(name='test')) # name=endpoint
# app.add_url_rule('/test', view_func=view函数) # name=endpoint

  2.CBV加装饰器和methods方法

def auth(func):
def inner(*args, **kwargs):
print('before')
result = func(*args, **kwargs)
print('after')
return result
return inner class X1View(views.MethodView):
methods = ['GET','POST']
decorators = [auth, ] def get(self):
return 'x1.GET' def post(self):
return 'x1.POST' app.add_url_rule('/x1', view_func=X1View.as_view(name='x1')) #name=endpoint

   3.执行@app.route('/index')

"""
生成类似dict的形式
{
'/index': index函数
}
1. decorator = app.route('/index')
2.
@decorator
def index():
return "index"
3. decorator(index)
"""
"""
Map() = [
Rule(rule=/index/ endpoint=None view_func=函数),
]
"""

  4.路由系统源码剖析

route函数

def route(self, rule, **options):
'''
rule为url 例子rule='/index'
''' def decorator(f):
endpoint = options.pop('endpoint', None)
'''
rule为/index,f为函数名
'''
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator

  

"""
这段说明 如果endpoint为空,类似django的url里的name字段,就使用当前函数的__name__做为endpoint
""" if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
"""
将options里封装了反向生成url
"""
options['endpoint'] = endpoint def _endpoint_from_view_func(view_func): assert view_func is not None, 'expected view func if endpoint ' \
'is not provided.'
return view_func.__name__
 def execute(app):
application_iter = app(environ, start_response) #对象加()执行__call__方法
try:
for data in application_iter:
write(data)
if not headers_sent:
write(b'')
finally:
if hasattr(application_iter, 'close'):
application_iter.close()
application_iter = None try:
execute(self.server.app) #self.server.app 应该为Flask对象

  可以看到 application_iter = app(environ, start_response) 就是调用代码获取结果的地方。

  要调用 app 实例,那么它就需要定义了 __call__ 方法,我们找到 flask.app:Flask 对应的内容:

  

  

def auth(func):
def inner(*args, **kwargs):
print('before')
result = func(*args, **kwargs)
print('after')
return result return inner @app.route('/index.html',methods=['GET','POST'],endpoint='index')
@auth
def index():
return 'Index' 或 def index():
return "Index" self.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])
or
app.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])
app.view_functions['index'] = index 或
def auth(func):
def inner(*args, **kwargs):
print('before')
result = func(*args, **kwargs)
print('after')
return result return inner class IndexView(views.View):
methods = ['GET']
decorators = [auth, ] def dispatch_request(self):
print('Index')
return 'Index!' app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) # name=endpoint 或 class IndexView(views.MethodView):
methods = ['GET']
decorators = [auth, ] def get(self):
return 'Index.GET' def post(self):
return 'Index.POST' app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) # name=endpoint @app.route和app.add_url_rule参数:
rule, URL规则
view_func, 视图函数名称
defaults=None, 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
endpoint=None, 名称,用于反向生成URL,即: url_for('名称')
methods=None, 允许的请求方式,如:["GET","POST"] strict_slashes=None, 对URL最后的 / 符号是否严格要求,
如:
@app.route('/index',strict_slashes=False),
访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
@app.route('/index',strict_slashes=True)
仅访问 http://www.xx.com/index
redirect_to=None, 重定向到指定地址
如:
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')

def func(adapter, nid):
return "/home/888"
@app.route('/index/<int:nid>', redirect_to=func)
subdomain=None, 子域名访问
from flask import Flask, views, url_for app = Flask(import_name=__name__)
app.config['SERVER_NAME'] = 'wupeiqi.com:5000' @app.route("/", subdomain="admin")
def static_index():
"""Flask supports static subdomains
This is available at static.your-domain.tld"""
return "static.your-domain.tld" @app.route("/dynamic", subdomain="<username>")
def username_index(username):
"""Dynamic subdomains are also supported
Try going to user1.your-domain.tld/dynamic"""
return username + ".your-domain.tld" if __name__ == '__main__':
app.run()

注册路由原理

from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter app = Flask(import_name=__name__) class RegexConverter(BaseConverter):
"""
自定义URL匹配正则表达式
"""
def __init__(self, map, regex):
super(RegexConverter, self).__init__(map)
self.regex = regex def to_python(self, value):
"""
路由匹配时,匹配成功后传递给视图函数中参数的值
:param value:
:return:
"""
return int(value) def to_url(self, value):
"""
使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
:param value:
:return:
"""
val = super(RegexConverter, self).to_url(value)
return val # 添加到flask中
app.url_map.converters['regex'] = RegexConverter @app.route('/index/<regex("\d+"):nid>')
def index(nid):
print(url_for('index', nid=''))
return 'Index' if __name__ == '__main__':
app.run() b. 自定制正则路由匹配

自定制正则路由匹配

@app.route('/user/<username>')
@app.route('/post/<int:post_id>')
@app.route('/post/<float:post_id>')
@app.route('/post/<path:path>')
@app.route('/login', methods=['GET', 'POST'])

路由注册方法

七、Flask特殊装饰器

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

app = Flask('xxxx',template_folder="templates")
app.secret_key = 'as923lrjks9d8fwlkxlduf' @app.before_request #类似于django的middleware
def bf():
if request.path == '/login':
return None
user_info = session.get('user_info')
if not user_info:
return redirect('/login') @app.route('/order',methods=['GET'])
def order():
return "order" @app.route('/index',methods=['GET'])
def index():
return "index" @app.route('/logout',methods=['GET'])
def logout():
del session['user_info']
return redirect('/login') @app.route('/login',methods=['GET','POST'])
def login():
if request.method == "GET":
return render_template('login.html')
else:
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'alex' and pwd == '':
session['user_info'] = user
return redirect('/index')
# return render_template('login.html',msg = "用户名或密码错误",x = 123)
return render_template('login.html',**{'msg':'用户名或密码错误'}) if __name__ == '__main__':
app.run()

用flask_middleware实现用户登录认证

  请求之前:@app.before_request

def before_request(self, f):

    #self.before_request_funcs = {}
#结果返回 {None: [bf1,bf2]}
# setdefault(None, [])会返回{None:[]}
self.before_request_funcs.setdefault(None, []).append(f) return f

  请求之后:

def after_request(self, f):
#{None:[af1,af2]}
self.after_request_funcs.setdefault(None, []).append(f)
return f

八、模版使用

import functools
from flask import Flask,render_template,request,redirect,session,Markup app = Flask('xxxx',template_folder="templates")
app.secret_key = 'as923lrjks9d8fwlkxlduf' @app.template_global() def sb(a1, a2):
return a1 + a2 @app.template_filter()
"""
类似django的filter
"""
def db(a1, a2, a3):
return a1 + a2 + a3 def fffff(value):
return Markup("<input type='text' value='%s' />" %(value,)) #与django的make_safe一样 @app.route('/index',methods=['GET'])
def index():
context = {
'k1': 'v1',
'k2': [11,22,33],
'k3':{
'name':'oldboy',
'age': 56
},
'k4':fffff
}
return render_template('index.html',**context) @app.route('/order',methods=['GET'])
def order():
return render_template('order.html') if __name__ == '__main__':
app.run()

1.模版基本使用

{% extends "layout.html" %} #继承

{% block content %}
<h1>欢迎进入系统</h1> {% include 'xxx.html'%} #类似django的include_tag
{% include 'xxx.html'%}
{% include 'xxx.html'%} <p>{{k1}}</p>
<p>{{k2.0}} {{k2[0]}}</p>
<ul>
{% for item in k2 %}
<li>{{item}}</li>
{% endfor %}
</ul> <p>{{k3.name}} {{k3['name']}} {{k3.get('name')}} </p> #可以用get,这样可以设置取不到为空不会出现异常
<ul>
{% for item in k3.keys() %}
<li>{{item}}</li>
{% endfor %}
</ul>
<ul>
{% for item in k3.values() %}
<li>{{item}}</li>
{% endfor %}
</ul>
<ul>
{% for k,v in k3.items() %}
{% if v == 'oldboy'%}
<li>老男人:{{k}} {{v}}</li>
{% else %}
<li>{{k}} {{v}}</li>
{% endif %}
{% endfor %}
</ul>
<h1>函数: {{k4('')}}</h1> #可以执行函数返回
<h1>全局函数: {{sb(1,2)}} {{ 1|db(2,3)}}</h1> #全局生效,类似于django的filter和simple_tag
{% endblock %}

2.html中模版的使用

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="height: 48px;">
头部内容
</div>
<div>
{% block content %} {% endblock %}
</div> <div style="height: 48px;">
底部内容
</div>
</body>
</html>

3.模版基类

{% extends "layout.html" %}

{% block content %}
<h1>订单列表</h1> {% endblock %}

4.模版继承

九、Flask-session源码剖析

  1.特殊的字典,当前类继承dict就具有dict的特性

class MyDict(dict):
def on_update(self):
pass v2 = MyDict()
v2['k1'] = 'v1'
print(v2,type(v2))
v3 = dict(v2)
print(v3,type(v3))

  2.flask请求进来先执行Flask类的__call__方法 将environ和start_response传入(请求相关的信息)

 def __call__(self, environ, start_response):
"""Shortcut for :attr:`wsgi_app`."""
return self.wsgi_app(environ, start_response)

   3. ctx = self.request_context(environ)将请求相关的数据传入Flask类的request_context方法,request_context方法实例化RequestContext,执行__init__

def request_context(self, environ):
#实例化RequestContext 执行__init__
return RequestContext(self, environ)

  4.RequestContext的构造方法中,再次实例化了request = app.request_class(environ) 一个request类将请求相关的数据封装到request类中,执行request的__init__方法

def __init__(self, app, environ, request=None):
self.app = app
if request is None:
request = app.request_class(environ) #封装
self.request = request
self.url_adapter = app.create_url_adapter(self.request)
self.flashes = None
self.session = None # Request contexts can be pushed multiple times and interleaved with
# other request contexts. Now only if the last level is popped we
# get rid of them. Additionally if an application context is missing
# one is created implicitly so for each level we add this information
self._implicit_app_ctx_stack = [] # indicator if the context was preserved. Next time another context
# is pushed the preserved context is popped.
self.preserved = False # remembers the exception for pop if there is one in case the context
# preservation kicks in.
self._preserved_exc = None

  5.通过ctx.push()=Request_Context.push()执行session的操作

def push(self):

    top = _request_ctx_stack.top
if top is not None and top.preserved:
top.pop(top._preserved_exc) app_ctx = _app_ctx_stack.top
if app_ctx is None or app_ctx.app != self.app:
app_ctx = self.app.app_context()
app_ctx.push()
self._implicit_app_ctx_stack.append(app_ctx)
else:
self._implicit_app_ctx_stack.append(None) if hasattr(sys, 'exc_clear'):
sys.exc_clear() _request_ctx_stack.push(self) #此处操作session
self.session = self.app.open_session(self.request)
if self.session is None:
self.session = self.app.make_null_session()

  6.open_session执行Flask类的 self.session_interface.open_session(self, request)

    Flask的 session_interface = SecureCookieSessionInterface()

    相当于执行了 SecureCookieSessionInterface类里的 open_session 方法

def open_session(self, app, request):
s = self.get_signing_serializer(app)
if s is None:
return None
val = request.cookies.get(app.session_cookie_name)
if not val:
return self.session_class()
“”“
self.session_class() = SecureCookieSession() SecureCookieSession继承了dict
”“”
max_age = total_seconds(app.permanent_session_lifetime)
try:
data = s.loads(val, max_age=max_age) #通过sercet_key进行编码
return self.session_class(data)
except BadSignature:
return self.session_class()

M1-Flask-Day1的更多相关文章

  1. python3 Flask -day1

    window 10  python 3 安装flask 首先打开cmd命令执行窗口切换到Python安装目录的Script,输入pip出现以下页面 这里我们使用virtualenv虚拟开发环境 为什么 ...

  2. THUSC2017 Day1题解

    THUSC2017 Day1题解 巧克力 题目描述 "人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道." 明明收到了一大块巧克力,里面有若干小块,排成n行m列.每一小块都有 ...

  3. Flask 学习(三)模板

    Flask 学习(三)模板 Flask 为你配置 Jinja2 模板引擎.使用 render_template() 方法可以渲染模板,只需提供模板名称和需要作为参数传递给模板的变量就可简单执行. 至于 ...

  4. Flask & Vue 构建前后端分离的应用

    Flask & Vue 构建前后端分离的应用 最近在使用 Flask 制作基于 HTML5 的桌面应用,前面写过<用 Python 构建 web 应用>,借助于完善的 Flask ...

  5. noip2013/day1/1/转圈游戏

    总时间限制:  10000ms 单个测试点时间限制:  1000ms 内存限制:  128000kB 描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从  ...

  6. 暑假集训Day1 整数划分

    题目大意: 如何把一个正整数N(N长度<20)划分为M(M>=1)个部分,使这M个部分的乘积最大.N.M从键盘输入,输出最大值及一种划分方式. 输入格式: 第一行一个正整数T(T<= ...

  7. 温故而知新--day1

    温故而知新--day1 变量类型 变量是计算机存储数据的内存空间,由于计算机可以处理不同的数据,不同的数据就要定义不同的数据类型.python的数据类型很多,还可以自定义数据类型,常用的一般数据类型有 ...

  8. Flask01 第一个flask项目

    参考地址:https://github.com/miguelgrinberg/microblog/tree/v0.1 flask环境[苹果M1] 添加虚拟环境 python3 -m venv venv ...

  9. 无意苦争春,一任群芳妒!M1 Mac book(Apple Silicon)能否支撑全栈工程师的日常?(Python3/虚拟机/Docker/Redis)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_187 就像大航海时代里突然诞生的航空母舰一样,苹果把玩着手心里远超时代的M1芯片,微笑着对Intel说:"不好意思,虽然 ...

  10. flask+sqlite3+echarts2+ajax数据可视化

    前提: 准备Python + Flask+Sqlite3的平台环境(windows系统) 前面一节介绍flask怎么安装了,剩下sqlite3下载后解压,然后环境变量添加解压路径就行了 附加下载地址: ...

随机推荐

  1. k8s(一) kubeadm简单集群初始化

    写给想入门kubernetes的同学们 # 系统版本 [root@master ~]# cat /etc/os-release NAME="CentOS Linux" VERSIO ...

  2. 文件操作 chardet使用

    #_*_coding:utf-8_*_ import chardet #f = open(file="兼职白领学生空姐模特护士联系方式.txt", mode="rb&qu ...

  3. 设置和安装 BizTalk Server 2016 的必备组件

    设置服务器,然后安装和配置软件必备组件. 加入本地管理员组       若要安装并配置 BizTalk Server,在本地计算机上使用管理员帐户登录到服务器. 向本地管理员组添加任何管理 BizTa ...

  4. Nginx 网络事件

    L27-29 应用层(如浏览器等一系列组成的发送get请求) 传输层 系统内核打开一个端口将客户端IP及端口和服务端IP及端口记录下来一并传输到网络层 网络层 打包后到链路层 再到客户端路由器至广域网

  5. 【C/C++】动态内存分配和链表

    本文对链表以及C/C++中的动态链表做详细诠释. 什么是链表? 链表是一种重要的数据结构,它最大的优点是可以进行动态的存储分配.链表有单向链表,双向链表,循环链表.对于c,这里我们只讨论单向链表. 我 ...

  6. 使用RestTemplate测试视频上传的Post请求

    以往多用RestTemplate处理接口的调用以及与Ribbon/Feign配合使用调用微服务接口,近日写了一个处理Post文件上传的解决方案,其实就是将后台所需的MultipartFile,在请求P ...

  7. kubernetes ceph-rbd挂载步骤 类型storageClass

    由于kubelet本身并不支持rbd的命令,所以需要添加一个kube系统插件: 下载插件 quay.io/external_storage/rbd-provisioner 下载地址: https:// ...

  8. linux-shell系列4-init

    #!/bin/bash # 过滤出MAC地址MAC=`ifconfig |awk '{print $5}'|sed -n '1p;1q'` # 过滤网卡名字NET_NAME=`ifconfig |aw ...

  9. python之旅六【第七篇】面向对象

    面向对象三大特性 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强... 面向对象编程 ...

  10. CH2401 送礼物(算竞进阶习题)

    双向dfs 数据不是很大,但是如果直接暴搜的话2^45肯定过不了的.. 所以想到乱搞!!要让程序跑的更快,肯定要减下搜索树的规模,再加上这道题双搜的暗示比较明显(逃),所以就来乱搞+双搜求解 所以先从 ...