当前位置: 首页 > news >正文

学习Flask之三、模板

学习Flask之三、模板

书写易于维护的应用的关键是书写整洁和良构的代码。到目前为止你所见的例子过于简单而不能体现这点。把两个目的完全独立的Flask view 函数当作一个来写,会产生问题。view函数的一个显然的任务是对请求作出响应,如前面的例子所示。对于简单的请求,这是足够的。但是通常请求会触发应用状态的改变,view函数是产生改变的来源地。

例如,考虑一下用户注册一个新的网站帐户。用户在网页的表单里输入email地址和密码,并点击提交按钮。在服务端,包含用户数据的请求到达,Flask把它分派给处理注册请求的view函数。这个view函数需要与数据库对话以添加新的用户然后产生响应送回浏览器。这两种类型的任务正规的称为业务逻辑和呈现逻辑。将业务逻辑和呈现逻辑混合会使代码难于理解和维护。将呈现逻辑转移到模板(templates有助于改进应用的可维护性。模板是包含响应文本的文件,带有表示动态部分的占位符变量,动态部只有请求上下文才知道。用真实值代替变量并返回最终响应字符的过程称为宣染(rendering)。对于宣染模板的任务,Flask提供了一个强大的模板引擎称为Jinja2

Jinja2模板引擎

最简单的形式,Jinja2模板是一个包含响应文本的文件。

Example 3-1展示了一个与Example 2-1中的index() view函数相匹配的Jinja2模板。

Example 3-1. templates/index.html: Jinja2 template

<h1>Hello World!</h1>

Example 2-2的view函数user()返回的响应有动态成份,用变量表示。

Example 3-2展示完成这种响应的模板。

Example 3-2. templates/user.html: Jinja2 template

<h1>Hello, {{ name }}!</h1>

宣染模板

黙认情况下,Flask从应用文件夹的templates子文件夹中查找模板。在下一版的hello.py里,你需要将前面的模板放在新的templates文件夹并命名为index.htmluser.html

需要修改应用的view函数以宣染模板。

Example 3-3展示这些更新。

Example 3-3. hello.py: Rendering a template

from flask import Flask, render_template

# ...

@app.route('/index')

def index():

return render_template('index.html')

@app.route('/user/<name>')

def user(name):

return render_template('user.html', name=name)

Flask提供的render_template集成Jinja2模板引擎。这个函数以模板的文件名作为第一个参数。任何其它的参数包括 key/value对,表示模板中引用的变量的实际值。本例中,第二个模板接收一个name 变量。

如果你不使用它们的话,前面的类似name=name的关键字参数很常见但是看起来很混淆而且难于理解。左边的“name”表示参数名,在模板文件中用作占位符。右边的“name” 是个当前范围的变量,提供同名参数的值。

变量

Example 3-2模板中使用的{{ name }}结构引用一个变量,一种特殊的占位符,告诉模板引擎那个位置的值应该来自从模板宣染时提供的数据。Jinja2可以识别任意类型的变量,即便是复杂的列表,字典和对象。如下是模板中使用变量额外的例子:

<p>A value from a dictionary: {{ mydict['key'] }}.</p>

<p>A value from a list: {{ mylist[3] }}.</p>

<p>A value from a list, with a variable index: {{ mylist[myintvar] }}.</p>

<p>A value from an object's method: {{ myobj.somemethod() }}.</p>

变量可以用过滤器修饰,它放在变量名后,用管道符分隔。例如,下面的模板显示首字符大写的name变量。

Hello, {{ name|capitalize }}

Table 3-1 列出了一些Jinja2里常用的过滤器。见:

http://www.aluoyun.cn/details.php?article_id=192

safe很有意思,值得强调。 黙认情况下出于安全目的Jinja2去除所有变量的tags。例如,如果变量设定值为 '<h1>Hello</h1>', Jinja2 会宣染值为'<h1>Hello</h1>',这会使得h1元素显示而不是被浏览器解释。很多时候有必要显示存贮于变量的HTML代码,这时候 safe过滤器派上用场。

对于不信任的值不要使用safe,例如用户在表单输入的文本。

关于过滤器的完全列表可以参见Jinja2官方文档。

控制结构

Jinja2 提供了多个控制结构可以用来改变模板。

本节介绍一些最有用的例子 。

下面的例子显示如何在模板里使用条件语句

{% if user %}

Hello, {{ user }}!

{% else %}

Hello, Stranger!

{% endif %}

模板里另一个常见需求是宣染元素的列表。本例展示如何用for循环来完成这个任务:

<ul>

{% for comment in comments %}

<li>{{ comment }}</li>

{% endfor %}

</ul>

Jinja2也支持macros,这与Python代码里的函数相似。例如:

{% macro render_comment(comment) %}

<li>{{ comment }}</li>

{% endmacro %}

<ul>

{% for comment in comments %}

{{ render_comment(comment) }}

{% endfor %}

</ul>

为了使macros可复用,可以把它存贮于单一的文件然后引入到需要它们的模板中:

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

<ul>

{% for comment in comments %}

{{ macros.render_comment(comment) }}

{% endfor %}

</ul>

需要在不同的地方重复的部分模板代码也可以存贮于单独的文件并在模板中包含它以免重复:

{% include 'common.html' %}

另一种强大的方法是通过模板继承,这与Python代码里的类的继承相似。首先创建基模板,命名为base.html:

<html>

<head>

{% block head %}

<title>{% block title %}{% endblock %} - My Application</title>

{% endblock %}

</head>

<body>

{% block body %}

{% endblock %}

</body>

</html>

这里block标记定义派生模板可以改变的元素。本例中,有head,title, 和body块;注意title包含于head。下面的模板是由基模板派生的:

{% extends "base.html" %}

{% block title %}Index{% endblock %}

{% block head %}

{{ super() }}

<style>

</style>

{% endblock %}

{% block body %}

<h1>Hello, World!</h1>

{% endblock %}

extends指令声明模板从base.html派生。这个指令跟着3个新的块定义,分别在合适的地方插入。注意head块的新的定义,它在基类中不是空的,所以用 super()保留原始的内容。本节中呈显的所有的控制结构的实际使用将在后面展示,所以你有机会看到它们是如何工作的。

    用Flask-Bootstrap集成Twitter Bootstrap

Bootstrap是来自Twitter的开源框架,提供了用户接口来创建简洁而有吸引力的兼容所有现代浏览器的网页。

Bootstrap是客户端的框架,所以服务器不会直接参与它。服务器需要做的是提供HTML响应,它引用 Bootstrap的CSS和JavaScript文件并通过HTML,CSS,和JavaScript代码实例化所需要的元素。完成所有这些的理想场所是在模板里。

很显然的方法是在应用中集成Bootstrap以对模板作必要的修改。更简单 的方法是使用Flask的扩展,称为Flask-Bootstrap以简化集成工作。可以用pip安装Flask-Bootstrap:

(venv) $ pip install flask-bootstrap

Flask扩展通常在应用实例创建的同时初始化。

Example 3-4 shows the initialization of Flask-Bootstrap.

Example 3-4. hello.py: Flask-Bootstrap initialization

from flask.ext.bootstrap import Bootstrap

# ...

bootstrap = Bootstrap(app)

如第二章的Flask-Script,Flask-Bootstrap 从flask_名字空间引入,并通过传入应用实例初始化。

一旦Flask-Bootstrap初始化,包含所有Bootstrap文件的基模板就可以被就用使用。

这个模板使用了Jinja2的模板继承;这个应用扩展具有通用网页结构的基模板包括引入 Bootstrap的元素。 Example 3-5展示新版本user.html作为衍生模板。

Example 3-5. templates/user.html: Template that uses Flask-Bootstrap

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block navbar %}

<div class="navbar navbar-inverse" role="navigation">

<div class="container">

<div class="navbar-header">

<button type="button" class="navbar-toggle"

data-toggle="collapse" data-target=".navbar-collapse">

<span class="sr-only">Toggle navigation</span>

<span class="icon-bar"></span>

<span class="icon-bar"></span>

<span class="icon-bar"></span>

</button>

<a class="navbar-brand" href="/">Flasky</a>

</div>

<div class="navbar-collapse collapse">

<ul class="nav navbar-nav">

<li><a href="/">Home</a></li>

</ul>

</div>

</div>

</div>

{% endblock %}

{% block content %}

<div class="container">

<div class="page-header">

<h1>Hello, {{ name }}!</h1>

</div>

</div>

{% endblock %}

Jinja2extends指令通过引用Flask-Bootstrapbootstrap/base.html实施模板继承来自Flask-Bootstrap的基模板提供了骨架网页以包含所有Bootstrap CSSJavaScript 文件。基模板定义了可以被派生模板重写的块。blockendblock指令定义添加到基模板的块的内容。前面的user.html模板定义三个块称为titlenavbarcontent

这些是基模块中被派生模板导出的所有的块。title非常直接,它的内容在HTML文件的header<title>标记内。保留navbar content块用作网页的导航栏和主内容。在这个模板里,navbar块定义一个简单的导航栏,使用Bootstrap元素。

content有一个容器<div>其中有网页的header第一个版本的欢迎行现在在网页的header里了。

Flask-Bootstrapbase.html模板定义了多个可以在派生模板中使用的其它块。Table 3-2 显示了所有的可用的块的列表。见:

http://www.aluoyun.cn/details.php?article_id=193

Table 3-2里的许多块被Flask-Bootstrap本身使用,所以直接重写它们会出现问题。例如,stylesscripts块是声明Bootstrap文件的地方。如果应用需要添加内容到一个已有内容的块,则必须使用Jinja2super()函数。例如,这里是如何在派生模板里书写scripts块来添加新的JavaScript文件到文档中:

{% block scripts %}

{{ super() }}

<script type="text/javascript" src="my-script.js"></script>

{% endblock %}

定义错误页

当你在浏览器的地址栏中输入无效的路由时,你会得到代码404的错误页。错误页太过直白不具吸引力,它也与使用Bootstrap的网页没有联系。Flask 允许应用自定义错误页,它可以基于模板,就像正常的路由一样。有两个最常见的错误代码是404,当客户端请求一个未知的网页或路由时触发,当出现未处理的意外时触发500代码。

Example 3-6展示如何为这两个错误提供自定义的处理器。

Example 3-6. hello.py: Custom error pages

@app.errorhandler(404)

def page_not_found(e):

return render_template('404.html'), 404

@app.errorhandler(500)

def internal_server_error(e):

return render_template('500.html'), 500

错误处理器返回响应,像view函数一样。它们也返回数值状态码与错误相应。错误处理器中引用的模板需要重写。这些模板要遵循一般网页的布局,这种情况下它们有导航栏和网页的header显示错误信息。书写这些模块的直接的方法是拷贝templates/user.html 到templates/404.html和 templates/500.html,然后改变网页的 header元素以适应错误信息。但是这样会产生在量的重复。Jinja2的模板继承可以帮助这一点。同样Flask-Bootstrap 提供了带有网页的基础布局的基模板,应用可以定义它自已的基模板使它具有更完整的页面布局包括导航栏和预留的网页内容以在派生模板中定义。

Example 3-7展示templates/base.html,一个派生自bootstrap/base.html的新的模板并定义导航栏,但它本身是其它模板如templates/user.html, templates/404.html, 和templates/500.html的基文件。

Example 3-7. templates/base.html: Base application template with navigation bar

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block navbar %}

<div class="navbar navbar-inverse" role="navigation">

<div class="container">

<div class="navbar-header">

<button type="button" class="navbar-toggle"

data-toggle="collapse" data-target=".navbar-collapse">

<span class="sr-only">Toggle navigation</span>

<span class="icon-bar"></span>

<span class="icon-bar"></span>

<span class="icon-bar"></span>

</button>

<a class="navbar-brand" href="/">Flasky</a>

</div>

<div class="navbar-collapse collapse">

<ul class="nav navbar-nav">

<li><a href="/">Home</a></li>

</ul>

</div>

</div>

</div>

{% endblock %}

{% block content %}

<div class="container">

{% block page_content %}{% endblock %}

</div>

{% endblock %}

这个模板的content块里只是一个容器 <div>元素它包含新的空块称为page_content,派生的模板可以定义。

应用的模板可以继承这些模板而不是直接自Flask-Bootstrap。

Example 3-8 显示自templates/base.html构建一个自定义的404错误页是多么的简单。

Example 3-8. templates/404.html: Custom code 404 error page using template inheritance

{% extends "base.html" %}

{% block title %}Flasky - Page Not Found{% endblock %}

{% block page_content %}

<div class="page-header">

<h1>Not Found</h1>

</div>

{% endblock %}

templates/user.html模板现在可以简单的继承自基模板,如Example 3-9所示。

Example 3-9. templates/user.html: Simplified page template using template inheritance

{% extends "base.html" %}

{% block title %}Flasky{% endblock %}

{% block page_content %}

<div class="page-header">

<h1>Hello, {{ name }}!</h1>

</div>

{% endblock %}

链接

任何有一个以上路由的应用都需要包含链接来连接不同的网页,例如导航栏。对于简单的路由来说在模板里书写URLs作为链接并不重要,但是对于有可变部分的动态路由来说在模板里构建URLs会变得复杂。而且,直接书写URLs会导致不想要的对于代码里定义的路由的依赖。如果路由是可识别的,模板里的链接会破裂。为了避免这些问题,Flask提供了url_for()函数,它产生URLs自贮存于应用的URL map的信息。

最简单的使用,这些函数取view函数名(或者 endpoint名作为app.add_url_route()定义的路由)作为单一参数并返回它的URL。

例如,当前版本的hello.py调用 url_for('index')将返回/。而调用url_for('index', _external=True) 将返回绝对的URL,本例为http://localhost:5000/。

在应用中连接不同的路由使用相对URLs已经足够了。在网页浏览器外有必要使用绝到路径,例如通过email发送链接。动态的URLs可以通过给url_for()传递动态部分作为关键字参数来产生。例如,url_for('user', name='john', _external=True)将返回http://localhost:5000/user/john。

发送到url_for()的关键字参数不限于动态路由使用的参数。这个函数可以增加任意参数到查询字符串。例如url_for('index', page=2)将返回/?page=2。

静态文件

网络应用不只是由Python代码和模板构成。许多的应用也用静态文件如images, JavaScript源文件,自HTML代码引用的CSS。

你可能记得当第2章的hello.py 应用的URL被检查时,它里面有静态的入口。这是因为引用静态文件被看作特殊的路由,用/static/<filename>定义。例如,调用url_for('static', filename='css/styles.css', _external=True)将返回http://localhost:5000/static/css/styles.css。

在黙认配置里,Flask从位于应用根目录的static子目录查找静态文件。如果有必要可以将文件放在这个目录的子目录里。当服务器从前面的例子接收URL时,它产生响应包含static/css/styles.css的内容。

Example 3-10 展示应用如何在基模板中包含favicon.ico以在浏览器的地址栏中显示。

Example 3-10. templates/base.html: favicon definition

{% block head %}

{{ super() }}

<link rel="shortcut icon" href="{{ url_for('static', filename = 'favicon.ico') }}"

type="image/x-icon">

<link rel="icon" href="{{ url_for('static', filename = 'favicon.ico') }}"

type="image/x-icon">

{% endblock %}

icon声明放在head块的后面。注意如何使用super()来保留基模板中定义的原始内容。

Flask-Moment来本地化DatesTimes

在网络应用中处理日期和时间并不简单当用户在不同的地方工作当。服务器需要统一时间单位,它不依赖于用户的位置,所以通常使用Coordinated Universal Time (UTC)。然而,对于用户,看 UTC时间很困惑,因为用户总是想看当地的日期和时间并与当地的格式对应。一个优雅的方案是发送时间单位到浏览器,然后转换为当地时间再宣染。对于这种任务浏览器可以很好的工作因为它们可以访问时区并在用户的计算机里本地化。

有一个优秀的客户端开源 JavaScript库在浏览器里宣染日期和时间,称为moment.js。Flask-Moment是Flask应用集成moment.js到 Jinja2模板的扩展。用pip安装Flask-Moment。

(venv) $ pip install flask-moment

这个扩展的初始化见Example 3-11。

Example 3-11. hello.py: Initialize Flask-Moment

from flask.ext.moment import Moment

moment = Moment(app)

Flask-Moment依赖于jquery.js 和 moment.js。这两个库需要在HTML文档的适当地方放置,可以直接放置,也可以通过扩展的帮助函数放置。它可以从CDN引用这些库的测试版。因为Bootstrap已经包含jquery.js,只有moment.js需要添加。 Example 3-12展示如何在其模板的scripts里加载这些库。

Example 3-12. templates/base.html: Import moment.js library

{% block scripts %}

{{ super() }}

{{ moment.include_moment() }}

{% endblock %}

要使用timestamps,Flask-Moment产生moment类给模板使用。

Example 3-13传递变量称为current_time给模板进行宣染。

Example 3-13. hello.py: Add a datetime variable

from datetime import datetime

@app.route('/')

def index():

return render_template('index.html',

current_time=datetime.utcnow())

Example 3-14 展示current_time是如何在模板里宣染的。

Example 3-14. templates/index.html: Timestamp rendering with Flask-Moment

<p>The local date and time is {{ moment(current_time).format('LLL') }}.</p>

<p>That was {{ moment(current_time).fromNow(refresh=True) }}</p>

format('LLL')格式按时区和客户计算机的本地设置宣染日期和时间。参数决定宣染的格式,从 'L'到 'LLLL'对应不同的等级。format()函数也可以接收自定义格式。 

第二行的fromNow()宣染相对时间并自动刷新。初期,这个时间截会显示为 “a few seconds ago,” 但是刷新项会让它更新,所以你打开网页几分钟你会看到内容变为“a minute ago,” “2 minutes ago,” 等等。

Flask-Moment实施format(), fromNow(), fromTime(), calendar(),

valueOf(), 和 unix() 方法自moment.js。更多的格式选项请见官方文档。

Flask-Moment假定服务端处理的时间截是原生的UTC表示的datetime对象。更详细的内容请见 datetime包的官方文档。 Flask-Moment宣染的时间截可以本地化到许多语言。可以给lang()函数传递语言选项:

{{ moment.lang('es') }}

通过上面讨论的技术,你可以构建用户友好的现代网页。下一章将会讨论如何通过表单与用户交互。

相关文章:

学习Flask之三、模板

学习Flask之三、模板 书写易于维护的应用的关键是书写整洁和良构的代码。到目前为止你所见的例子过于简单而不能体现这点。把两个目的完全独立的Flask view 函数当作一个来写&#xff0c;会产生问题。view函数的一个显然的任务是对请求作出响应&#xff0c;如前面的例子所示。对…...

2023-02-20干活小计:

所以我今天的活开始了&#xff1a; In this paper, the authors target the problem of Multimodal Name Entity Recognition(MNER) as an improvement on NER(text only) The paper proposes a multimodal fusion based on a heterogeneous graph of texts and images to mak…...

LeetCode_动态规划_困难_1326.灌溉花园的最少水龙头数目

目录1.题目2.思路3.代码实现&#xff08;Java&#xff09;1.题目 在 x 轴上有一个一维的花园。花园长度为 n&#xff0c;从点 0 开始&#xff0c;到点 n 结束。 花园里总共有 n 1 个水龙头&#xff0c;分别位于 [0, 1, …, n] 。 给你一个整数 n 和一个长度为 n 1 的整数数…...

mac tcpdump学习

学习原因 工作上遇到了重启wifi后无法发出mDNS packet的情况&#xff0c;琢磨一下用tcpdump用的命令如下 sudo tcpdump -n -k -s 0 -i en0 -w VENDOR-DUT-INTERFACE.pcapng是在测airplay BCT认证时&#xff0c;官方文档的解决方法。对tcpdump很不了解&#xff0c;现汇总如下的学…...

【跟我一起读《视觉惯性SLAM理论与源码解析》】第二章 编程及编译工具

23.2.21终于拿到六哥的新书 感觉很是不错&#xff0c;打算近期写一写心得之类的 废话不多说&#xff0c;直接开啃 PS&#xff1a;我的建议是阅读完十四讲后再来看这本书&#xff0c;效果应该会很不错。 因为第一章都是介绍之类的我觉得没什么整理的必要&#xff0c;所以直接来…...

广东望京卡牌科技有限公司,2023年团建活动圆满举行

玉兔初临&#xff0c;春天相随&#xff0c;抖擞精神&#xff0c;好运连连。春天是一个万物复苏的季节&#xff0c;来自广东的望京卡牌科技有限公司&#xff0c;也迎来了新年第一次团建活动。在“乘风破浪、追逐梦想”的口号声中&#xff0c;2023望京卡牌目标启动会团结活动正式…...

ts语法如何在Vue3中运用?

一、父子传值的用法 父传子&#xff1a;defineProps的TS写法 // 父组件&#xff1a;和 vue2 一样正常传值 <template><div class"login-page"><cp-nav-bar title"登录" right-text"注册"></cp-nav-bar></div> &…...

RK3566添加湿度传感器以及浅析hal层

RK3566添加一款温湿度传感器gxht3x.挂在i2c总线下。驱动部分就不多做解析。大致流程硬件接好i2c线以及vcc gnd。后看数据手册。初始化寄存器&#xff0c;然后要读数据的话读那个寄存器&#xff0c;读出来的数据要做一个转化,然后实现open read write ioctl函数就行了。本文主要…...

看了这份Java高级笔试宝典覆盖近3年Java笔试中98%高频知识点,反打面试官

首先声明&#xff1a; 本书覆盖了近3年程序员面试笔试中超过98%Java高频知识点&#xff0c;当你细细品读完本书后&#xff0c;面试都是小问题。 一书在手/工作不愁 记住重点&#xff0c;考试要考 前言 程序员求职始终是当前社会的一个热点&#xff0c;而市面上有很多关于程…...

从0到1搭建大数据平台之监控

大家好&#xff0c;我是脚丫先生 (o^^o) 大数据平台设计中&#xff0c;监控系统尤为重要。 它时刻关乎大数据开发人员的幸福感。 试想如果半夜三更&#xff0c;被电话吵醒解决集群故障问题&#xff0c;那是多么的痛苦&#xff01;&#xff01;&#xff01; 但是不加班是不可…...

采购评标管理过程是怎样的?有哪些评标标准?

采购活动的评标是检查和比较投标的有组织的过程&#xff0c;以选择最佳报价&#xff0c;努力获得实现企业目标所需的货物、工程和服务。 评标是由一个被称为评标小组的机构负责。这个小组如何称呼&#xff0c;取决于企业的情况。同义词有报价审查小组、投标审查委员会或投标审…...

《Vue+Spring Boot前后端分离开发实战》专著累计发行上万册

杰哥的学术专著《VueSpring Boot前后端分离开发实战》由清华大学出版社于2021年3月首次出版发行&#xff0c;虽受疫情影响但热度不减&#xff0c;受到业界读者的热捧&#xff0c;截至今日加印5次&#xff0c;累计发行12000册&#xff0c;引领读者开发前后端分离项目&#xff0c…...

类与类之间的关系有哪几种?

文章目录程序设计要素1.可读性2.健壮性3.优化4.复用性5.可扩展性设计类的关系遵循的原则1、 高内聚低耦合2、面向对象开发中 “针对接口编程优于针对实现编程”&#xff0c;”组合优于继承” 的总体设计类与类之间的关系&#xff08;即事物关系&#xff09; A is-a B 泛化&…...

LeetCode 606.根据二叉树创建字符串,102.二叉树的层序遍历和牛客 二叉搜索树与双向链表

文章目录1. 根据二叉树创建字符串2. 二叉树的层序遍历3. 二叉搜索树与双向链表1. 根据二叉树创建字符串 难度 简单 题目链接 解题思路&#xff1a; 这里的意思就是&#xff1a;用前序遍历遍历这颗树。然后左子树和右子树分别在一个括号里。括号里的规则是&#xff1a; 1.左右都…...

02-18 周六 图解机器学习之SMV 第五章5-2

02-18 周六 图解机器学习之SMV 第五章5-2时间版本修改人描述2023年2月18日11:47:18V0.1宋全恒新建文档 环境 程序的基本环境&#xff0c;是使用了jupyter&#xff0c;在容器中运行的。 简介 本程序主要演示支持向量的获取&#xff0c;支持向量是距离超平面最近的点组成的。程序…...

Spring Boot系列--创建第一个Spring Boot项目

1.项目搭建 在IDEA中新建项目&#xff0c;选择Spring Initializr。 填写项目信息&#xff1a; 选择版本和Spring Web依赖&#xff1a; Spring Web插件能为项目集成Tomcat、配置dispatcherServlet和xml文件。此处选择的版本若为3.0.2的话会出现如下错误&#xff1a; java: …...

手把手教你用React Hook和TypeScript从零实现虚拟滚动列表组件

前言 k8s 全称 kubernetes&#xff0c;这个名字大家应该都不陌生&#xff0c;k8s是为容器服务而生的一个可移植容器的编排管理工具&#xff0c;集应用的部署和运维&#xff0c;负载均衡&#xff0c;服务发现和扩容&#xff0c;版本回滚于一身&#xff0c;越来越多的公司正在拥…...

界面控件DevExpress WPF Pivot Grid——拥有强大多维数据分析能力!

界面控件DevExpress WPF的Pivot Grid组件是一个类似excel的数据透视表&#xff0c;用于多维数据分析和跨选项卡报表生成。它拥有众多的布局自定义选项&#xff0c;允许开发者完全控制其UI且以用户为中心的功能使其易于部署。PS&#xff1a;DevExpress WPF拥有120个控件和库&…...

python字典及基础操作

1) 字典是没有顺序的&#xff0c;是任意对象的无序集合。 2) 字典的键是唯一的&#xff0c;不能多次出现&#xff0c;多次出现时取最后一个值。 3) 键是不可变的。 4) 字典中的元素可增删。 5) 因为没有顺序&#xff0c;所以不存在索引。 1. 字典元素的访问 >>> …...

Windows Server 2008 R2安装onlyoffice【docker】

目录 前言 准备工作 安装docker 安装onlyoffice 常见问题 前言 目前docker for windows只能在windows10/11上安装&#xff0c;其他的windows版本只能使用Docker Toolbox来安装&#xff0c;使用该工具安装的docker其实是借助了Oracle VM VirtualBox虚拟机来运行的&a…...

JVM学习笔记六:运行时数据区之堆

目录 概述 堆空间内部结构 JDK7版本 JDK8版本 堆空间的内存划分 堆空间大小设置参数 概述 Java堆是虚拟机所管理的内存中最大的一块&#xff0c;其在JVM启动时即被创建&#xff0c;并且空间大小也被确定&#xff08;这里是不考虑Java8之后以本地内存来实现的元空间&…...

usb闪存驱动器数据恢复该怎么进行?3个方法总结

“怎么办&#xff1f;我的USB驱动器不知道因为什么原因&#xff0c;里面的数据、文件都消失了。有没有什么方法在没有进行备份的情况下恢复从U盘丢失的数据&#xff1f;” USB驱动器作为最常用的存储移动设备&#xff0c;里面保存着各种文件数据。但是有时会出现损坏而导致数据…...

DAX 微信 markdown 编辑器

DAX 微信 markdown 编辑器 一、致谢 感谢开源项目&#xff1a; md wechat-format 感谢 WordPress 插件 Mine云点播 作者 mine27 的指导。 二、如何使用 打开如下地址&#xff0c;直接编辑&#xff0c;可以实时看到符合微信公众号排版的效果。 推荐访问&#xff1a;https://j…...

湖南中创教育为学员提供方便快速的退费服务

2006年&#xff0c;湖南中创教育科技有限公司创始人团队开始创业进入职业教育行业&#xff1b;2014年公司正式成立&#xff0c;组建专业团队并转型升级“互联网”&#xff0c;进入在线教育行业。 自主研发“中创网校”学习平台&#xff0c;为学员提供了集直播、视频回放复习、…...

Java 给视频添加背景音乐 | Java工具

目录 前言 Maven依赖 环境依赖 代码 总结 前言 本文提供给视频添加背景音乐的java工具&#xff0c;一如既往的实用主义。 Maven依赖 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.1.1…...

【JUC2022】第二章 多线程锁

【JUC2022】第二章 多线程锁 文章目录【JUC2022】第二章 多线程锁一、乐观锁与悲观锁1.悲观锁2.乐观锁二、八锁案例1.标准情况&#xff0c;有a、b两个线程&#xff0c;请问先打印邮件还是短信【结果&#xff1a;邮件】2.sendEmail方法中加入暂停3秒钟&#xff0c;请问先打印邮件…...

快学会这个技能-.NET API拦截技法

大家好&#xff0c;我是沙漠尽头的狼。 本文先抛出以下问题&#xff0c;请在文中寻找答案&#xff0c;可在评论区回答&#xff1a; 什么是API拦截&#xff1f;一个方法被很多地方调用&#xff0c;怎么在不修改这个方法源码情况下&#xff0c;记录这个方法调用的前后时间&…...

stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)

文章目录一、uart_init&#xff08;串口初始化&#xff09;二、USART1_IRQHandler&#xff08;串口1中断服务程序&#xff09;三、main.c&#xff08;主函数&#xff09;四、关于printf的支持一、uart_init&#xff08;串口初始化&#xff09; 就是根据上一篇的一样的步骤&…...

Hystrix资源隔离

目录资源隔离使用资源隔离的好处基于Hystrix实现微服务中资源隔离基于Hystrix线程池隔离实现资源隔离利用 HystrixCommand 获取单条数据利用 HystrixObservableCommand 批量获取数据基于 Hystrix 信号量机制实现资源隔离资源隔离 资源隔离是什么&#xff1f; 资源隔离是指把对…...

字符串(一)-- LeetCode[3] 无重复字符的最长子串

1 无重复字符的最长子串 1.1 题目描述 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的最长子串的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示例 2: 输入: s “bbbbb” 输出: 1 解释…...