Flask应用的基本组成部分、模板引擎Jinja2的使用、Flask-WTF、SQLAlchemy

news2024/11/14 19:24:22

目录标题

      • 1. Flask应用的基本组成部分
        • 1.1 路由(Routing)
        • 1.2 视图函数(View Function)
        • 1.3 请求(Request)
        • 1.4 响应(Response)
      • 2. 模板引擎Jinja2的使用
        • 2.1 入门案例
        • 2.2 条件判断
        • 2.3 循环遍历
        • 2.4 过滤器
        • 2.5 宏
        • 2.6 定义临时变量
        • 2.7 定义模板
      • 3. Flask-WTF表单处理和验证
        • 3.1 安装 Flask-WTF
        • 3.2 定义表单类
          • 3.2.1 字段类型和验证器
          • 3.2.2 综合案例
        • 3.3 渲染表单
        • 3.4 处理表单提交
      • 4. 数据库操作和SQLAlchemy
        • 4.1 安装
        • 4.2 配置数据库连接
        • 4.3 定义数据模型类
        • 4.4 数据操作

1. Flask应用的基本组成部分

Flask应用的基本组成部分包括路由、视图函数、请求和响应。

1.1 路由(Routing)

路由(Routing)是将URL映射到相应的视图函数(View Function)上的过程。

在Flask中,可以通过装饰器来定义路由,如下所示:

from flask import Flask

app = Flask(__name__) # 实例化一个Flask对象,最基本的写法

@app.route('/')
def index():
    return 'Hello, World!'

if __name__ == "__main__":
    app.run()

在Python中,装饰器(decorator)是一种特殊的函数,用于修改或增强其他函数的功能。装饰器是通过在被装饰函数的定义前加上@符号,将被装饰函数传递给装饰器函数作为参数来实现的。

在上面的代码中,我们通过app.route装饰器定义了一个路由,将/映射到index函数上。当用户在浏览器中访问/时,就会执行index函数,并返回'Hello, World!'这个字符串。

1.2 视图函数(View Function)

上面的例子中,index函数就是一个视图函数。

Flask应用中处理请求并返回响应的函数。视图函数通常会接收一些参数(如URL中的参数POST请求中的表单数据等),并根据这些参数进行处理,最后返回一个响应(如HTML页面、JSON数据等)。

1.3 请求(Request)

请求是Flask应用中接收客户端发来的数据的对象。

每次客户端发送一个HTTP请求时,Flask将会创建一个request对象。

在视图函数中,我们可以通过request对象获取客户端提交的数据(如表单数据、URL 参数等)。例如,下面的代码中,我们通过request.args.get方法获取了URL参数中的name参数:

from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def index():
    name = request.args.get('name', 'World')
    return f'Hello, {name}!'

在浏览器中访问/?name=Flask,就会返回'Hello, Flask!'这个字符串。

下面是request一些常用的方法和属性:

  • request.method:HTTP请求方法,如 GET、POST、PUT、DELETE 等。
  • request.args:获取查询参数,返回一个不可变字典。
  • request.form:获取表单参数,返回一个不可变字典。
  • request.files:获取上传的文件,返回一个不可变字典。
  • request.headers:获取请求头,返回一个字典。
  • request.cookies:获取请求中的 cookies,返回一个字典。
  • request.remote_addr:获取客户端的 IP 地址。
  • request.path:获取请求路径,不包含查询参数。
  • request.url:获取完整的请求 URL。
  • request.is_xhr:判断请求是否是 AJAX 请求。
提取方法描述
request.cookies提取cookie字典信息
request.args.get(“name”)查询字符串参数 /user?name=curry&age=18
request.form.get(“name”)表单数据 {“name”: “james”, “age”: 38}
request.json.get(“name”)json格式字符串参数

参考连接:http://t.csdn.cn/kFwUR

1.4 响应(Response)

响应是Flask应用中返回给客户端的数据。

在视图函数中,我们可以通过return语句返回响应。

响应可以是各种格式的数据,如HTML页面、JSON数据、图片、文件等。例如,下面的代码中,我们返回了一个HTML页面:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return '<html><body><h1>Hello, World!</h1></body></html>'

在浏览器中访问 /,就会显示一个标题为'Hello, World!'的 HTML 页面。

在Flask中,我们可以使用make_response()函数来创建一个响应对象,并可以通过设置其内容、状态码、头部等属性来进行自定义。

例如,以下代码定义了一个包含自定义内容和状态码的响应:

from flask import Flask, make_response

app = Flask(__name__)

@app.route('/')
def hello_world():
    response = make_response('Hello World!', 200)
    # 这里设置了一个自定义的响应头,键为 'X-My-Header',值为 'my-value'
    response.headers['X-My-Header'] = 'my-value'
    return response

下面是response一些常用的方法和属性:

  • response.status_code:HTTP 响应状态码,如 200、404 等。
  • response.headers:HTTP 响应头,可以通过该属性设置自定义的响应头,返回一个字典。
  • response.content_type:HTTP 响应内容的 MIME 类型,如 text/html、application/json 等。
  • response.data:HTTP 响应内容,返回一个字节串。
  • response.set_cookie():设置 cookie。
  • response.delete_cookie():删除 cookie。
  • response.make_response():创建一个 Response 对象,可以通过该方法自定义响应内容和响应头。

官网地址:https://flask.palletsprojects.com/en/latest/

2. 模板引擎Jinja2的使用

Jinja2中文文档_w3cschool

Jinja2是Flask默认的模板引擎,它是一种基于Python语言的模板引擎,具有简单、高效、安全等特点。

Jinja2支持模板继承、变量替换、条件判断、循环遍历等常用的模板操作。

在Flask中,我们可以通过在应用程序中配置模板路径,然后在视图函数中使用render_template函数来渲染模板,将动态数据和静态内容结合起来,最终生成一个完整的HTML页面。

2.1 入门案例

来看一个例子,演示如何在Flask应用中使用Jinja2模板引擎:

# app.py
from flask import Flask, render_template

app = Flask(__name__)
app.config['TEMPLATES_AUTO_RELOAD'] = True   # 设置模板自动重载

@app.route('/')
def index():
    return render_template('index.html', name='John Doe')

我们在Flask应用的根目录下创建一个templates文件夹,并在该文件夹下创建一个名为 index.html的模板文件。在该模板文件中,我们可以使用Jinja2提供的语法来渲染动态数据和静态内容。

image-20230226221318273

以下是一个简单的 index.html 模板文件的示例:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>{{ name }} - My Flask App</title>
  </head>
  <body>
    <h1>Hello, {{ name }}!</h1>
  </body>
</html>
  • {{ name }}:表示要渲染的动态数据,其中 name 是我们在视图函数中传递给模板的参数。

最后,我们可以通过访问 http://localhost:5000/ 来查看渲染后的页面效果,页面将会显示 Hello, John Doe!
Alt

注意:

  • app.config['TEMPLATES_AUTO_RELOAD'] = True 是 Flask 应用中配置模板自动重载的参数。如果将其设置为 True,则在修改模板文件后,Flask 会自动重载模板,从而使得修改后的模板能够生效。这在开发阶段非常有用,因为可以避免每次修改模板后都需要手动重启应用的麻烦。

csdn链接:http://t.csdn.cn/ENFfK

2.2 条件判断

<!-- 条件判断 -->
{% if condition %}
    <p>条件为真</p>
{% elif other_condition %}
    <p>其他条件为真</p>
{% else %}
    <p>所有条件都为假</p>
{% endif %}

2.3 循环遍历

<!-- 循环遍历 -->
{% for item in items %}
    <li>{{ item }}</li>
{% else %}
	<!-- 当 for 循环没有遍历到任何一个元素时,执行 else 代码块中的内容 -->
    <li>列表为空</li>
{% endfor %}

2.4 过滤器

过滤器可以用管道符|链接到变量之后。

例如,我们有一个变量name,我们可以使用capitalize过滤器将它的第一个字母大写:

{{ name | capitalize }}

还可以使用多个过滤器,其中每个过滤器的输出作为下一个过滤器的输入,如下所示:

{{ name | lower | replace(" ", "_") }}

上面把变量name中的所有字母都转换为小写,并将空格替换为下划线。

Jinja2中的常见过滤器包括:

  • safe: 标记值为安全,将不进行转义
  • capitalize: 将字符串的第一个字符大写
  • lower: 将字符串转换为小写
  • upper: 将字符串转换为大写
  • title: 将字符串的每个单词的首字母大写
  • trim: 删除字符串开头和结尾的空白字符
  • replace: 将字符串中的某个子串替换为另一个字符串

2.5 宏

宏是 Jinja2 中可重用的代码块,可以在模板的任何地方调用。

通过使用 Jinja2 中的 {% macro %} 标签定义宏,然后可以在模板的任何地方调用它。例如:

{% macro hello(name) %}
  <h1>Hello, {{ name }}!</h1>
{% endmacro %}

这个宏定义了一个 hello 的宏,它接受一个名为 name 的参数,并返回一个带有 nameh1 标签。假设该宏在一个名为 hello_macro.html 的模板文件。

接下来,我们在另一个模板文件中使用这个宏。内容如下:

{% import 'hello_macro.html' as macros %}

{{ macros.hello('World') }}

这个文件中首先使用了 import 指令将 hello_macro.html 中的宏导入,并定义了一个名为 macros 的命名空间来包含这个宏。然后,我们就可以在文件中使用这个宏了。

最终生成的 HTML 代码将是:

<h1>Hello, World!</h1>

如果是在同一文件调用:

{{ hello('World') }}

下面是一个相对复杂的例子:

{% macro render_person(person) %}
    <div class="person">
        <h2>{{ person.name }}</h2>
        <p>Age: {{ person.age }}</p>
        {% if person.email %}
            <p>Email: {{ person.email }}</p>
        {% endif %}
    </div>
{% endmacro %}

{% for person in people %}
    {{ render_person(person) }}
{% endfor %}
  • 在上面的例子中,我们定义了一个名为 render_person 的宏,用于渲染一个人的信息。
  • 它接受一个 person 对象作为参数,并使用该对象的属性来渲染 HTML。
  • 在主模板中,我们使用 for 循环来遍历人的列表,并使用 render_person 宏来渲染每个人的信息。

2.6 定义临时变量

<!-- with定义临时变量 -->
{% with title="Hello, World!" %}
    <h1>{{ title }}</h1>
{% endwith %}

{% with total = 1 + 2 %}
	<!-- total=3 -->
    {{ total }}
{% endwith %}

使用with定义的变量作用范围在{% with %}{% endwith %}之间。

还可以使用set定义临时变量:

{% set x = 1 %}
{% if x %}
  {% set y = 2 %}
{% endif %}

{{ x }}  # 输出 1
{{ y }}  # 报错,y未定义

set 的作用范围是定义它的块级范围,块级范围内的变量名只在该块级范围内有效,出了这个范围,这个变量名就失效了。

在这个例子中,{% set x = 1 %} 定义了变量 x,作用范围为整个模板。在 if 语句中,当 x 的值为真时,{% set y = 2 %} 定义了变量 y,作用范围为 if 语句块级范围。因此,当 if 语句的条件为假时,变量 y 未被定义,因此输出时会报错。

宏和临时变量:

  • 宏是一段重复使用的代码块,它可以在模板中定义并在需要的地方调用。而临时变量则是在模板中定义的一个变量,它可以用来存储临时数据,并在模板中使用。
  • 宏和临时变量的区别在于它们的作用范围和生命周期不同。宏是一段代码块,它的作用范围只在它所定义的模板中,它的生命周期是整个应用程序的生命周期。而临时变量的作用范围只在当前的上下文中,它的生命周期只是当前请求处理过程中。

2.7 定义模板

在 Flask 中,可以通过定义基础模板扩展模板来实现代码的复用和管理,使得代码更加简洁和易于维护。

定义基础模板可以使用 {% block %}{% endblock %} 标签,其中 {% block %} 定义了一个块,其内容可以被子模板继承和覆盖。

在子模板中可以使用 {% extends %} 标签继承基础模板,同时通过 {% block %} 标签覆盖父模板中定义的块。

举个例子,假设我们有一个父模板 base.html,它包含了一个名为 content 的块。现在我们想要创建一个子模板 child.html,它继承自父模板并重写 content 块,可以这样实现:

<!-- base.html -->
<!doctype html>
<html>
  <head>
    <title>{% block title %}{% endblock %}</title>
  </head>
  <body>
    <div id="content">
      {% block content %}{% endblock %}
    </div>
  </body>
</html>
<!-- child.html -->
{% extends "base.html" %}

{% block title %}Child Template{% endblock %}

{% block content %}
  <h1>Hello, World!</h1>
{% endblock %}

在子模板中:

  • 我们使用 {% extends "base.html" %} 声明了它继承自 base.html
  • 使用 {% block ... %} ... {% endblock %} 块声明了要重写的内容。
  • 这样,child.html 就拥有了 base.html 中的所有内容,并且可以根据自己的需求覆盖 base.html 中的块内容。
  • 当子模板被渲染时,Jinja2 会先加载父模板 base.html,然后替换其中的 content 块为子模板 child.html 中定义的内容。

3. Flask-WTF表单处理和验证

  • 在 Flask 中,表单处理和验证一般使用 Flask-WTF 插件实现。
  • Flask-WTF 是 Flask 的一个扩展,它集成了 WTForms,是一个流行的 Python 表单处理库。使用 Flask-WTF 可以方便地创建表单,并对表单数据进行验证和处理。
  • 在 Flask-WTF 中,表单通常是通过定义一个继承自 FlaskForm 类的类来实现的。这个类中定义了表单中各个字段的类型、标签、验证规则等信息。
  • 使用 Flask-WTF 中的 form 对象可以在模板中生成表单,并通过 validate_on_submit() 方法对表单数据进行验证和处理。

3.1 安装 Flask-WTF

pip install Flask-WTF

3.2 定义表单类

在 Flask 中定义表单类可以使用 Flask-WTF 扩展中的 FlaskForm 类,也可以使用 WTForms 库中的 Form 类。后面主要以使用 FlaskForm 为例。

每个表单字段都是一个实例变量,可以设置不同的参数,如字段类型、标签、验证规则等。

例如,如果需要使用字符串类型字段和数据验证器,可以这样定义表单类:

from flask_wtf import FlaskForm
from wtforms import StringField, validators

class MyForm(FlaskForm):
    name = StringField('Name', validators=[validators.DataRequired()])

在上面的代码中,定义了一个名为 MyForm 的表单类,其中包含一个字符串类型的 name 字段,该字段使用了 DataRequired 验证器,用于验证该字段的值是否为空。

3.2.1 字段类型和验证器

常用的字段类型:

字段类型描述
StringField字符串字段,用于接受字符串类型的数据
IntegerField整型字段,用于接受整数类型的数据
DecimalField十进制浮点型字段,用于接受浮点型数据,可以指定精度
BooleanField布尔型字段,用于接受 True 或 False 类型的数据
DateField日期型字段,用于接受日期类型的数据
TimeField时间型字段,用于接受时间类型的数据
DateTimeField日期时间型字段,用于接受日期时间类型的数据
FileField文件上传字段,用于接受上传文件类型的数据
RadioField单选按钮字段
CheckboxField复选框字段

验证器:

DataRequired确保字段不为空message
EqualTo比较两个字段的值是否相等message, fieldname
Length确保字段值的长度在给定范围内message, min, max
Email确保字段值是合法的电子邮件地址message
URL确保字段值是合法的 URL 地址message
NumberRange确保字段值在数字范围内message, min, max
Regexp使用正则表达式验证字段值message, regex
Optional使字段变为可选项

参数message表示自定义错误提示信息。如果参数未指定,则使用默认的错误提示信息。

3.2.2 综合案例
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualTo

class RegistrationForm(FlaskForm):
    """
    注册表单类
    """
    username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Sign Up')

这个表单类定义了一个用户注册表单,包含用户名、电子邮件、密码和确认密码等字段。

其中,StringField表示字符串类型的字段,PasswordField表示密码类型的字段,SubmitField表示提交按钮类型的字段。

验证器中,DataRequired表示该字段必须填写,Length表示该字段长度限制,Email表示该字段必须是电子邮件格式,EqualTo表示该字段必须与另一个字段相等。

最后,submit表示提交按钮。

3.3 渲染表单

视图函数中,可以通过创建一个表单对象来渲染表单,并将其传递给模板进行渲染。

在模板中,可以使用 form.<field_name> 来渲染表单字段。

下面是一个简单的视图函数的示例:

from flask import render_template
from app import app
from forms import LoginForm

@app.route('/login')
def login():
    form = LoginForm()
    return render_template('login.html', form=form)

3.4 处理表单提交

处理表单提交时的一般流程如下:

  1. 用户在浏览器端填写表单并点击“提交”按钮,浏览器向服务器发送POST请求;
  2. Flask应用接收到请求,解析请求体中的表单数据,生成一个request对象;
  3. Flask应用根据请求的URL和请求方法选择对应的视图函数进行处理;
  4. 视图函数从request对象中获取表单数据,对数据进行验证和处理;
  5. 如果表单数据验证通过,视图函数进行相应的业务逻辑处理;
  6. 如果表单数据验证不通过,视图函数返回一个带有错误信息的响应,通常是重新渲染表单页面,并在页面中显示相应的错误信息;
  7. 视图函数根据业务逻辑的处理结果,生成响应对象,并返回给客户端。

4. 数据库操作和SQLAlchemy

在Flask中,常用的数据库操作有两种方式:

  1. 使用原生的SQL语句操作数据库。
  2. 使用ORM框架操作数据库,常用的ORM框架有SQLAlchemy。

下面我们主要介绍使用SQLAlchemy的方式。

SQLAlchemy是Python中最著名的ORM框架之一,它提供了高度封装的SQL操作方式,可以让我们使用Python语言来操作数据库,而不用编写复杂的SQL语句。

SQLAlchemy还提供了非常好的数据模型定义方式,可以大大减少我们编写数据库代码的工作量。

4.1 安装

pip install SQLAlchemy

4.2 配置数据库连接

安装完成后,我们需要在Flask应用中配置数据库连接,以便于在应用中使用。Flask中的数据库连接配置通常保存在app.config对象中。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username:password@hostname/database_name'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

上面的代码中,我们定义了一个Flask应用,并使用SQLAlchemy连接到了一个MySQL数据库。

其中,'username’和’password’分别是数据库用户名和密码,'hostname’是数据库服务器地址,'database_name’是数据库名。

4.3 定义数据模型类

在Flask应用中,我们需要定义数据模型类,以便于ORM框架进行数据操作。

下面是一个简单的数据模型类的定义:

from datetime import datetime
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(60), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    def __repr__(self):
        return '<User {}>'.format(self.name)

上面的代码中,我们定义了一个User数据模型类,它继承自db.Model类,这个类是SQLAlchemy提供的基类,用来定义数据模型类。

在User类中,我们定义了表名、字段名和字段类型等信息,这些信息会被SQLAlchemy自动映射到数据库中。

在__repr__方法中,我们定义了打印对象时的输出信息。

4.4 数据操作

定义好数据模型类之后,我们就可以使用ORM框架进行数据操作了。

ORM框架提供了各种各样的查询方法,例如查询所有数据、查询单个数据、过滤数据等。

下面是一些简单的查询方法的例子:

# 查询所有用户
users = User.query.all()

# 查询第一个用户
user = User.query.first()

# 根据id查询用户
user = User.query.get(1)

# 过滤数据
users = User.query.filter_by(name='Alice').

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

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

相关文章

Python采集m3u8格式做个小姐姐动态壁纸~

人生苦短&#xff0c;我用python 首先&#xff0c;我和大家一样喜欢看小姐姐~ 其次&#xff0c;看美丽的事物会让人更加有动力去… 我编不下去了哈哈哈&#xff0c;我就是爱看充满美感的人儿~ 更多python好看的:点击此处跳转文末名片获取 环境 Pythonpycharm 模块使用 第…

使用virtualenv和pip构建项目所需的独立Python环境

1、为什么需要独立的Python环境&#xff1f;在讲技术前&#xff0c;想先讲讲目的。为什么我们需要独立的Python环境&#xff1f;这里就借用virtualenv的文档来解释吧。virtualenv is a tool to create isolated Python environments.The basic problem being addressed is one …

51-Jenkins-Periodic Backup插件实现Jenkins备份

Periodic Backup插件实现Jenkins备份前言目录结构插件备份安装插件使用插件前言 本篇来学习下使用Periodic Backup插件实现Jenkins备份 目录结构 Jenkins的所有数据都是存放在文件中的&#xff0c;所以&#xff0c;Jenins备份其实就是备份Jenkins_HOME目录。 Jenkins_Home目…

taobao.user.buyer.get( 查询买家信息API )

&#xffe5;开放平台基础API必须用户授权 查询买家信息API&#xff0c;只能买家类应用调用。 公共参数 请求地址: HTTP地址 http://gw.api.taobao.com/router/rest 公共请求参数: 公共响应参数: 请求参数 响应参数 点击获取key和secret 请求示例 TaobaoClient client new…

现在00后都是这么卷了吗?

现在的00后小年轻真的卷得过分了。前段时间我们公司来了个00年的&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 最近和他聊了一次天&#xff0c;原来这位小老弟家…

我应该把毕业设计做到什么程度才能过关?

本篇博客包含了狗哥多年职业生涯对于软件项目的一丢丢理解&#xff0c;也讲述了对于大学生毕业设计的一些理解。如果你还是懵懵懂懂就要离开学校了&#xff0c;被老师告知不得不做出一套毕业设计的时候&#xff0c;希望你可以看到这篇博客&#xff0c;让你有点头绪&#xff0c;…

PingCAP 唐刘:一个咨询顾问对 TiDB Chat2Query Demo 提出的脑洞

导读 近日&#xff0c;TiDB Cloud 发布了 Chat2Query 功能&#xff0c;在 TiDB Cloud 上通过自然语言提问&#xff0c;即可生成相应的 SQL&#xff0c;通过 TiDB Cloud 对上传的任意数据集进行分析。Gartner 也在一份有关 ChatGPT 对数据分析影响研究的报告中提及了 PingCAP 的…

Gateway集成Netty服务

Gateway和Netty都有盲区的感觉&#xff1b; 一、Netty简介 Netty是一个异步的&#xff0c;事件驱动的网络应用框架&#xff0c;用以快速开发高可靠、高性能的网络应用程序。 传输服务&#xff1a;提供网络传输能力的管理&#xff1b; 协议支持&#xff1a;支持常见的数据传输…

Python调用百度AI实现文字识别

目录标题 前沿实战演示重中之重(开玩笑)前沿 今天我们也来高大上一下,玩一把人工智能。那就是免费调用百度AI实现图片上面的文字识别。相对于Python的第三方库,百度人工智能要更强大,毕竟人工智能不是那么容易搞的。要调用,其实很简单,关键的代码只需要三行。但需要先注…

使用cmake在win10编译yolov5+tensorRT+cuda+cudnn+protobuf代码进行混合编译

这里进行之前需要把protobuf在win10下编译&#xff0c;可以参考这篇文章从Linux下载下来的工程代码&#xff0c;这里建议直接使用vs系列打开不要用vscode打开&#xff0c;vscode对win下的cmake不友好&#xff0c;主要体现在报错机制无法直接定位&#xff0c;题主的环境是vs2022…

Kubernetes07:Service

Kubernetes07:Service 1、service存在的意义 因为Pod的IP是不断变化的&#xff0c;所以需要注册service防止pod失联 1&#xff09;为了防止Pod失联&#xff08;服务发现&#xff09; 2、定义一组Pod访问策略&#xff08;负载均衡&#xff09; 2、Pod和Service的关系-------通…

为什么要学习C++软件调试技术?掌握这类技术都有哪些好处?

目录 1、为什么要学习C软件调试技术&#xff1f; 1.1、IDE调试手段虽必不可少&#xff0c;但还不够 1.2、通过查看日志和代码去排查异常崩溃问题&#xff0c;费时费力&#xff0c;很难定位问题 1.3、有的问题很难复现&#xff0c;可能只在客户的环境才能复现 1.4、为了应对…

主打的就是I/O流,顺便把File复习了

文章目录1. File类1.1 预备知识1.2 创建文件1.3 文件的常用方法2. IO流2.1 InputStream2.2 OutputStream2.3 Reader2.4 Writer2.5 缓冲流2.6 转换流2.7 对象流2.8 打印流1. File类 1.1 预备知识 文件分隔符 Windows&#xff1a;D:\Soft\QQ\PluginLinux&#xff1a;D:/Soft/QQ…

SpringMVC使用 redis 实现缓存

简介 SpringMVC 中也可以将缓存标签和 redis 结合起来使用&#xff0c;其实此时缓存没有起作用&#xff0c;只是通过缓存的那几个注解来操作 redis 而已&#xff1b;SpringMVC 中整合 redis 比较麻烦的是注意版本冲突的问题&#xff0c;如下是官网有关于版本的要求 https://d…

【人脸识别】DDL:数据分布知识蒸馏思想,提升困难样本(遮挡、低分辨率等)识别效果

论文题目&#xff1a;《Improving Face Recognition from Hard Samples via Distribution Distillation Loss》 论文地址&#xff1a;https://arxiv.org/pdf/2002.03662v3.pdf 代码地址&#xff1a;https://github.com/HuangYG123/DDL 1.前言及相关工作 Large facial variatio…

秒懂算法 | 基于图神经网络的推荐算法

图神经网络(Graph Neural Networks,GNN)是近几年兴起的学科,用来作推荐算法自然效果也相当好,但是要学会基于图神经网络的推荐算法之前,需要对图神经网络自身有个了解。 图卷积网络(Graph Convolutional Networks,GCN)提出于2017年。GCN 的出现标志着图神经网络的出现。深度学习…

大家一起来找茬,新手第一次layout到底能挑出多少毛病?

有一个新手工程师在论坛上发了一篇帖子&#xff0c;把自己的处女PCB布线图贴出来。 如果不看其他网友的评论&#xff0c;你能看出多少问题呢&#xff1f;可以在留言区和我们互动哦~ 帖子里他还提出了自己的小见解&#xff1a;问一下&#xff0c;我觉得自动布线挺好用的啊&#…

汽车标定知识整理(一):标定简介与CCP报文协议简介

目录 一、什么是标定 二、XCP与CCP 三、CCP报文协议简介 1、CCP报文协议简介 &#xff08;1&#xff09;CRO&#xff1a;Command Receive Object &#xff0c;命令接收对象&#xff08;由Master -> Slave&#xff09; &#xff08;2&#xff09;DTO&#xff1a;Data T…

Kotlin 39. Dependency Injection依赖注入以及Hilt在Kotlin中的使用,系列2:手动依赖注入

一起来学Kotlin&#xff1a;概念&#xff1a;26. Dependency Injection依赖注入以及Hilt在Kotlin中的使用&#xff0c;系列2&#xff1a;手动依赖注入 此系列博客中&#xff0c;我们将主要介绍&#xff1a; Dependency Injection&#xff08;依赖注入&#xff09; 概念介绍。…

当IDEA加载一个MAVEN新项目时,加载不成功,无法加载依赖的解决方法

当IDEA加载一个MAVEN新项目时&#xff0c;加载不成功&#xff0c;无法加载依赖的解决方法 此文为练习项目时的错误记录 当使用IDEA引入一个MAVEN新项目时&#xff0c;点击Reload maven按钮加载不成功&#xff0c;显示如下图界面&#xff1a; 在项目中的代码显示报红&#xff0c…