M1-Flask-Day1
前情概要
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的更多相关文章
- python3 Flask -day1
window 10 python 3 安装flask 首先打开cmd命令执行窗口切换到Python安装目录的Script,输入pip出现以下页面 这里我们使用virtualenv虚拟开发环境 为什么 ...
- THUSC2017 Day1题解
THUSC2017 Day1题解 巧克力 题目描述 "人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道." 明明收到了一大块巧克力,里面有若干小块,排成n行m列.每一小块都有 ...
- Flask 学习(三)模板
Flask 学习(三)模板 Flask 为你配置 Jinja2 模板引擎.使用 render_template() 方法可以渲染模板,只需提供模板名称和需要作为参数传递给模板的变量就可简单执行. 至于 ...
- Flask & Vue 构建前后端分离的应用
Flask & Vue 构建前后端分离的应用 最近在使用 Flask 制作基于 HTML5 的桌面应用,前面写过<用 Python 构建 web 应用>,借助于完善的 Flask ...
- noip2013/day1/1/转圈游戏
总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 128000kB 描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从 ...
- 暑假集训Day1 整数划分
题目大意: 如何把一个正整数N(N长度<20)划分为M(M>=1)个部分,使这M个部分的乘积最大.N.M从键盘输入,输出最大值及一种划分方式. 输入格式: 第一行一个正整数T(T<= ...
- 温故而知新--day1
温故而知新--day1 变量类型 变量是计算机存储数据的内存空间,由于计算机可以处理不同的数据,不同的数据就要定义不同的数据类型.python的数据类型很多,还可以自定义数据类型,常用的一般数据类型有 ...
- Flask01 第一个flask项目
参考地址:https://github.com/miguelgrinberg/microblog/tree/v0.1 flask环境[苹果M1] 添加虚拟环境 python3 -m venv venv ...
- 无意苦争春,一任群芳妒!M1 Mac book(Apple Silicon)能否支撑全栈工程师的日常?(Python3/虚拟机/Docker/Redis)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_187 就像大航海时代里突然诞生的航空母舰一样,苹果把玩着手心里远超时代的M1芯片,微笑着对Intel说:"不好意思,虽然 ...
- flask+sqlite3+echarts2+ajax数据可视化
前提: 准备Python + Flask+Sqlite3的平台环境(windows系统) 前面一节介绍flask怎么安装了,剩下sqlite3下载后解压,然后环境变量添加解压路径就行了 附加下载地址: ...
随机推荐
- codeforces525B
Pasha and String CodeForces - 525B Pasha got a very beautiful string s for his birthday, the string ...
- Servlet篇 之 web服务器
创建web项目,在web项目中创建html页面,然后把项目部署到web服务器里面,启动服务器之后,可以使用浏览器通过URL地址的方式,访问到web项目中的html页面了 Web服务器: 常用tomca ...
- Android 控件绑定封裝
最近刚开始写android 随便记录一下,以后还会修改 绑定ListView,Spinner 先创建绑定项: BaseItem public class BaseItem { public BaseI ...
- 「POJ - 1003」Hangover
BUPT 2017 summer training (16) #2C 题意 n个卡片可以支撑住的长度是1/2+1/3+1/4+..+1/(n+1)个卡片长度.现在给出需要达到总长度,求最小的n. 题解 ...
- 【BZOJ4832】抵制克苏恩(矩阵快速幂,动态规划)
[BZOJ4832]抵制克苏恩(矩阵快速幂,动态规划) 题面 BZOJ 题解 一模一样 #include<iostream> #include<cstdio> using na ...
- Codeforces Round #555 (Div. 3)[1157]题解
不得不说这场div3是真的出的好,算得上是从我开始打开始最有趣的一场div3.因为自己的号全都蓝了,然后就把不经常打比赛的dreagonm的号借来打这场,然后...比赛结束rank11(帮dreago ...
- [luogu1972][bzoj1878][SDOI2009]HH的项链【莫队+玄学卡常】
题目大意 静态区间查询不同数的个数. 分析 好了,成功被这道题目拉低了AC率... 打了莫队T飞掉了,真的是飞掉了QwQ. 蒟蒻想不出主席树的做法,就换成了莫队... 很多人都不知道莫队是什么... ...
- Nginx-Cluster 构建
nx-Cluster and ReverseProxyServer-----------ReProxy-------------------------Client-----------192.168 ...
- Naive Operations HDU6315 (杭电多校2G)
让ci = ai / bi, 求sum(ci)的值,因为每次 ai 都是加一的,那么我可以用一颗线段树来维护每个 i 位置的 ai 距离达到 bi 还需要的数的最小值,更新是每次都减一,如果我某一个区 ...
- 【lua】lua安装学习
Lua 是用标准C语言编写并以源代码形式开放的一种轻量小巧的脚本语言,设计目的是为了嵌入应用程序中,为应用程序提供灵活的扩展和定制功能. lua官网 http://www.lua.org/ 安装lua ...