flask库中sessions.py的使用小结

2025-07-27 20:50

本文主要是介绍flask库中sessions.py的使用小结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《flask库中sessions.py的使用小结》在Flask中Session是一种用于在不同请求之间存储用户数据的机制,Session默认是基于客户端Cookie的,但数据会经过加密签名,防止篡改,...

在 Flask 中,Session(会话) 是一种用于在不同请求之间存储用户数据的机制。Flask 的 Session 默认是基于 客户端 Cookie 的,但数据会经过加密签名,防止篡改(但内容本身是可读的,除非额外加密)。

1. Flask Session 的基本使用

(1) 启用 Session

Flask 的 Session 基于 flask.session,它是一个类似字典的对象。使用时需要设置 SECRET_KEY(用于签名 Session 数据,防止篡改):

from flask import Flask, session

app = Flask(__name__)
app.secret_key = 'your-secret-key-here'  # 必须设置,否则 Session 无法工作

(2) 存储和读取 Session

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

app = Flask(__name__)
app.secret_key = 'your-secret-key'

@app.route('/login')
def login():
    session['username'] = 'admin'  # 存储 Session
    session['logged_in'] = True    # Session 可以存储任意可序列化的数据
    return "Logged in!"

@app.route('/dashboard')
def dashboard():
    if session.get('logged_in'):
        return f"Welcome, {session['username']}!"
    else:
        return redirect(url_for('login'))

@app.route('/logout')
def logout():
    session.pop('username', None)  # 移除 Session 中的某个键
    session.clear()                # 清空整个 Session
    return "Logged out!"

(3) Session 的持久性(Permanent Session)

默认情况下,Session 在浏览器关闭后失效。如果要让 Session 长期有效(基于 PERMANENT_SESSION_LIFETIME 配置):

from datetime import timedelta

app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)  # 7天后过期

@app.route('/login')
def login():
    session.permanent = True  # 启用持久 Session
    session['username'] = 'admin'
    return "Logged in (persistent)!"

2. Flask Session 的工作原理

(1) 默认实现(SecureCookieSession)

Flask 的 Session 默认使用 SecureCookieSession,数据存储在 客户端 Cookie 中,但经过签名(防止篡改)。

数据格式

{
    "username": "admin",
    "_fresh": True,
    "_id": "abc123...",
    "_permanent": True
}

签名机制:使用 itsdangerous 库进行签名,确保数据不被篡改(但内容可读)。

(2) 如何修改 Session 存储方式?

默认的 Cookie Session 有大小限制(通常 4KB),如果需要存储大量数据,可以改用 服务端 Session(如 Redis数据库):

from flask_session import Session  # 需要安装 flask-session

app.config['SESSION_TYPE'] = 'redis'  # 可选 China编程redis, memcached, filesystem 等
app.config['SESSION_PERMANENT'] = True
app.config['SESSION_USE_SIGNER'] = True  # 是否签名 Cookie
app.config['SESSION_KEY_PREFIX'] = 'myapp:'  # Redis 键前缀

Session(app)  # 替换默认的 Session 实现

然后 flask.session 会自动使用 Redis 存储数据,而不是 Cookie。

3. Session 的安全配置

(1) 安全相关的 Cookie 设置

app.config.update(
    SESSION_COOKIE_NAME='my_session',       # Cookie 名称
    SESSION_COOKIE_HTTPONLY=True,          # 禁止 JavaScript 访问
    SESSION_COOKIE_SECURE=True,            # 仅 HTTPS 传输
    SESSION_COOKIE_SAMESITE='Lax',         # 防 CSRF(Strict/Lax/None)
    SESSION_COOKIE_PARTITIONED=True,       # 跨站 Cookie 隔离(CHIPS)
)

(2) 防止 Session 劫持

  • 使用 SESSION_USE_SIGNER=True(默认启用)防止篡改。
  • 避免在 Session 中存储敏感信息(如密码),因为 Cookie 内容可被用户读取(即使签名)。

4. 常见问题

(1)RuntimeError: The session is unavailable because no secret key was set.

原因:未设置 SECRET_KEY
解决

app.secret_key = 'your-secret-key' # 必须设置

(2) Session 数据不持久

原因:默认 Session 在浏览器关闭后失效。
解决

session.permanent = True
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=30)

(3) 如何强制 Session 过期?

@app.route('/clear_session')
def clear_session():
    session.clear()  # 清空 Session
    return "Session cleared!"

5. 总结

特性说明
默认存储客户端 Cookie(签名防篡改)
持久性session.permanent = True + PERMANENT_SESSION_LIFETIME
安全配置HTTPOnly、Secure、SameSite
扩展存储使用 flask-session 支持 Redis、数据库等
适用场景小型数据(如用户登录状态),大数据需用服务端存储

如果需要更安全的 Session 方案,建议:

  • 使用 服务端 Session(Redis) 替代 Cookie。
  • 避免存储敏感数据在 Session 中。
  • 启用 Secure + SameSite 防 CSRF。

Sessions.py

from __future__ import annotations

import collections.abc as c
import hashlib
import typing as t
from collections.abc import MutableMapping
from datetime import datetime
from datetime import timezone

from itsdangerous import BadSignature
from itsdangerous import URLSafeTimedSerializer
from werkzeug.datastructures import CallbackDict

from .json.tag import TaggedJSONSerializer

if t.TYPE_CHECKING:  # pragma: no cover
    import typing_extensions as te

    from .app import Flask
    from .wrappers import Request
    from .wrappers import Response


class SessionMixin(MutableMapping[str, t.Any]):
    """Expands a basic dictionary with session attributes."""

    @property
    def permanent(self) -> bool:
        """This reflects the ``'_permanent'`` key in the dict."""
        return self.get("_permanent", False)

    @permanent.setter
    def permanent(self, value: bool) -> None:
        self["_permanent"] = bool(value)

    #: Some implementations can detect whether a session is newly
    #: created, but that is not guaranteed. Use with caution. The mixin
    # default is hard-coded ``False``.
    new = False

    #: Some implementations can detect changes to the session and set
    #: this when that happens. The mixin default is hard coded to
    #: ``True``.
    modified = True

    #: Some implementations can detect when session data is read or
    #: written and set this when that happens. The mixin default is hard
    #: coded to ``True``.
    Accessed = True


class SecureCookieSession(CallbackDict[str, t.Any], SessionMixin):
    """Base class for sessions based on signed cookies.

    This session backend will set tChina编程he :attr:`modified` and
    :attr:`accessed` attributes. It cannot reliably track whether a
    session is new (vs. empty), so :attr:`new` remains hard coded to
    ``False``.
    """

    #: When data is changed, this is set to ``True``. Only the session
    #: dictionary itself is tracked; if the session contains mutable
    #: data (for example a nested dict) then this must be set to
    #: ``True`` manually when modifying that data. The session cookie
    #: will only be written to the response if this is ``True``.
    modified = False

    #: When data is read or written, this is set to ``True``. Used by
    # :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie``
    #: header, which allows caching proxies to cache different pages for
    #: different users.
    accessed = False

    def __init__(
        self,
        initial: c.Mapping[str, t.Any] | c.Iterable[tuple[str, t.Any]] | None = None,
    ) -> None:
        def on_update(self: te.Self) -> None:
            self.modified = True
            self.accessed = True

        super().__init__(initial, on_update)

    def __getitem__(self, key: str) -> t.Any:
        self.accessed = True
        return super().__getitem__(key)

    def get(self, key: str, default: t.Any = None) -> t.Any:
        self.accessed = True
        return super().get(key, default)

    def setdefault(self, key: str, default: t.Any = None) -> t.Any:
        self.accessed = True
        return super().setdefault(key, default)


class NullSession(SecureCookieSession):
    """Class used to generate nicer error messages if sessions are not
    available.  Will still allow read-only access to the empty session
    but fail on setting.
    """

    def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn:
        raise RuntimeError(
            "The session is unavailable because no secret "
            "key was set.  Set the secret_key on the "
            "application to something unique and secret."
        )

    __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail  # noqa: B950
    del _fail


class SessionInterface:
    """The basic interface you have to implement in order to replace the
    default session interface which uses werkzeug's securecookie
    implementation.  The only methods you have to implement are
    :meth:`open_session` and :meth:`save_sessijavascripton`, the others have
    useful defaults which you don't need to change.

    The session object returned by the :meth:`open_session` method has to
    provide a dictionary like interface plus the properties and methods
    from the :class:`SessionMixin`.  We recommend just subclassing a dict
    and adding that mixin::

        class Session(dict, SessionMixin):
            pass

    If :meth:`open_session` returns ``None`` Flask will call into
    :meth:`make_null_session` to create a session that acts as replacement
    if the session support cannot work because some requirement is not
    fulfilled.  The default :class:`NullSession` class that is created
    will complain that the secret key was not set.

    To replace the session interface on an application all you have to do
    is to assign :attr:`flask.Flask.session_interface`::

        app = Flask(__name__)
        app.session_interface = MySessionInterface()

    Multiple requests with the same session may be sent and handled
    concurrently. When implementing a new session interface, consider
    whether reads or writes to the backing store must be synchronized.
    There is no guarantee on the order in which the session for each
    request is opened or saved, it will occur in the order that requests
    begin and end processing.

    .. versionadded:: 0.8
    """

    #: :meth:`make_null_session` will look here for the class that should
    #: be created when a null session is requested.  Likewise the
    #: :meth:`is_null_session` method will perform a typecheck against
    #: this type.
    null_session_class = NullSession

    #: A flag that indicates if the session interface is pickle based.
    #: This can be used by Flask extensions to make a decision in regards
    #: to how to deal with the session object.
    #:
    #: .. versionadded:: 0.10
    pickle_based = False

    def make_null_session(self, app: Flask) -> NullSession:
        """Creates a null session which acts as a replacement object if the
        real session support could not be loaded due to a configuration
        error.  This mainly aids the user experience because the job of the
        null session is to still support lookup without complaining but
        modifications are answered with a helpful error message of what
        failed.

        This creates an instance of :attr:`null_session_class` by default.
        """
        return self.null_session_class()

    def is_null_session(self, obj: object) -> bool:
        """Checks if a given object is a null session.  Null sessions are
        not asked to be saved.

        This checks if the object is an instance of :attr:`null_session_class`
        by default.
        """
        return isinstance(obj, self.null_session_class)

    def get_cookie_name(self, app: Flask) -> str:
        """The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``."""
        return app.config["SESSION_COOKIE_NAME"]  # type: ignore[no-any-return]

    def get_cookie_domain(self, app: Flask) -> str | None:
        """The value of the ``Domain`` parameter on the session cookie. If not set,
        browsers will only send the cookie to the exact domain it was set from.
        Otherwise, they will send it to any subdomain of the given value as well.

        Uses the :data:`SESSION_COOKIE_DOMAIN` config.

        .. versionchanged:: 2.3
            Not set by default, does not fall back to ``SERVER_NAME``.
        """
        return app.config["SESSION_COOKIE_DOMAIN"]  # type: ignore[no-any-return]

    def get_cookie_path(self, app: Flask) -> str:
        """Returns the path for which the cookie should be valid.  The
        default implementation uses the value from the ``SESSION_COOKIE_PATH``
        config var if it's set, and falls back to ``APPLICATION_ROOT`` or
        uses ``/`` if it's ``None``.
        """
        return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"]  # type: ignore[no-any-return]

    def get_cookie_httponly(self, app: Flask) -> bool:
        """Returns True if the session cookie should be httponly.  This
        currently just returns the value of the ``SESSION_COOKIE_HTTPONLY``
        config var.
        """
        return app.config["SESSION_COOKIE_HTTPONLY"]  # type: ignore[no-any-return]

    def get_cookie_secure(self, app: Flask) -> bool:
        """Returns True if the cookie should be secure.  This currently
        just returns the value of the ``SESSION_COOKIE_SECURE`` setting.
        """
        return app.config["SESSION_COOKIE_SECURE"]  # type: ignore[no-any-return]

    def get_cookie_samesite(self, app: Flask) -> str | None:
        """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the
        ``SameSite`` attribute. This currently just returns the value of
        the :data:`SESSION_COOKIE_SAMESITE` setting.
        """
        return app.config["SESSION_COOKIE_SAMESITE"]  # type: ignore[no-any-return]

    def get_cookie_partitioned(self, app: Flask) -> bool:
        """Returns True if the cookie should be partitioned. By default, uses
        the value of :data:`SESSION_COOKIE_PARTITIONED`.

        .. versionadded:: 3.1
        """
        return app.config["SESSION_COOKIE_PARTITIONED"]  # type: ignore[no-any-return]

    def get_expiration_time(self, app: Flask, session: SessionMixin) -> datetime | None:
        """A helper method that returns an expiration date for the session
        or ``None`` if the session is linked to the browser session.  The
        default implementation returns now + the permanent session
        lifetime configured on the application.
        """
        if session.permanent:
            return datetime.now(timezone.utc) + app.permanent_session_lifetime
        return None

    def should_set_cookie(self, app: Flask, session: SessionMixin) -> bool:
        """Used by session backends to determine if a ``Set-Cookie`` header
        should be set for this session cookie for this response. If the session
        has been modified, the cookie is set. If the session is permanent and
        the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is
        always set.

        This check is usually skipped if the session was deleted.

        .. versionadded:: 0.11
        """

        return session.modified or (
            session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"]
        )

    def open_session(self, app: Flask, request: Request) -> SessionMixin | None:
        """This is called at the beginning of each request, after
        pushing the request context, before matching the URL.

        This must return an object which implements a dictionary-like
        interface as well as the :class:`SessionMixin` interface.

        This will return ``None`` to indicate that loading failed in
        some way that is not immediately an error. The request
        context will fall back to using :meth:`make_njsull_session`
        in this case.
        """
        raise NotImplementedError()

    def save_session(
        self, app: Flask, session: SessionMixin, response: Response
    ) -> None:
        """This is called at the end of each request, after generating
        a response, before removing the request context. It is skipped
        if :meth:`is_null_session` returns ``True``.
        """
        raise NotImplementedError()


session_json_serializer = TaggedJSONSerializer()


def _lazy_sha1(string: bytes = b"") -> t.Any:
    """Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include
    SHA-1, in which case the import and use as a default would fail before the
    developer can configure something else.
    """
    return hashlib.sha1(string)


class SecureCookieSessionInterface(SessionInterface):
    """The default session interface that stores sessions in signed cookies
    through the :mod:`itsdangerous` module.
    """

    #: the salt that should be applied on top of the secret key for the
    #: signing of cookie based sessions.
    salt = "cookie-session"
    #: the hash function to use for the signature.  The default is sha1
    digest_method = staticmethod(_lazy_sha1)
    #: the name of the itsdangerous supported key derivation.  The default
    #: is hMAC.
    key_derivation = "hmac"
    #: A python serializer for the payload.  The default is a compact
    #: JSON derived serializer with support for some extra Python types
    #: such as datetime objects or tuples.
    serializer = session_json_serializer
    session_class = SecureCookieSession

    def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None:
        if not app.secret_key:
            return None

        keys: list[str | bytes] = []

        if fallbacks := app.config["SECRET_KEY_FALLBACKS"]:
            keys.extend(fallbacks)

        keys.append(app.secret_key)  # itsdangerous expects current key at top
        return URLSafeTimedSerializer(
            keys,  # type: ignore[arg-type]
            salt=self.salt,
            serializer=self.serializer,
            signer_kwargs={
                "key_derivation": self.key_derivation,
                "digjavascriptest_method": self.digest_method,
            },
        )

    def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None:
        s = self.get_signing_serializer(app)
        if s is None:
            return None
        val = request.cookies.get(self.get_cookie_name(app))
        if not val:
            return self.session_class()
        max_age = int(app.permanent_session_lifetime.total_seconds())
        try:
            data = s.loads(val, max_age=max_age)
            return self.session_class(data)
        except BadSignature:
            return self.session_class()

    def save_session(
        self, app: Flask, session: SessionMixin, response: Response
    ) -> None:
        name = self.get_cookie_name(app)
        domain = self.get_cookie_domain(app)
        path = self.get_cookie_path(app)
        secure = self.get_cookie_secure(app)
        partitioned = self.get_cookie_partitioned(app)
        samesite = self.get_cookie_samesite(app)
        httponly = self.get_cookie_httponly(app)

        # Add a "Vary: Cookie" header if the session was accessed at all.
        if session.accessed:
            response.vary.add("Cookie")

        # If the session is modified to be empty, remove the cookie.
        # If the session is empty, return without setting the cookie.
        if not session:
            if session.modified:
                response.delete_cookie(
                    name,
                    domain=domain,
                    path=path,
                    secure=secure,
                    partitioned=partitioned,
                    samesite=samesite,
                    httponly=httponly,
                )
                response.vary.add("Cookie")

            return

        if not self.should_set_cookie(app, session):
            return

        expires = self.get_expiration_time(app, session)
        val = self.get_signing_serializer(app).dumps(dict(session))  # type: ignore[union-attr]
        response.set_cookie(
            name,
            val,
            expires=expires,
            httponly=httponly,
            domain=domain,
            path=path,
            secure=secure,
            partitioned=partitioned,
            samesite=samesite,
        )
        response.vary.add("Cookie")

1. 会话(Session)的核心类

(1)SessionMixin

作用:为字典形式的 Session 提供扩展属性。

关键属性

  • permanent:标记 Session 是否为持久会话(基于 _permanent 键值)。
  • new:标记 Session 是否为新创建的(默认为 False)。
  • modified:标记 Session 是否被修改(默认为 True)。
  • accessed:标记 Session 是否被访问(默认为 True)。

(2)SecureCookieSession

作用:基于签名 Cookie 的默认 Session 实现(继承自 CallbackDict 和 SessionMixin)。

特点

  • 自动跟踪修改状态(modified)和访问状态(accessed)。
  • 数据变更时会触发回调,确保状态同步。
(3)NullSession

作用:当未配置密钥时,提供一个安全的空 Session 替代品。

行为

  • 允许读取操作(返回空值)。
  • 拒绝写入操作(直接抛出 RuntimeError)。

2. 会话接口(SessionInterface)

(1) 核心方法

  • open_session(app, request)
    功能:在请求开始时加载 Session。
    返回:需实现类字典接口 + SessionMixin 的对象,失败时返回 None(触发 NullSession)。

  • save_session(app, session, response)
    功能:在请求结束时保存 Session 到响应。
    注意:若 is_null_session(session) 为 True 则跳过。

(2) Cookie 配置方法

  • get_cookie_name():从配置 SESSION_COOKIE_NAME 获取 Cookie 名称。
  • get_cookie_domain():控制 Cookie 的 Domain 属性(默认无子域名共享)。
  • get_cookie_secure():根据 SESSION_COOKIE_SECURE 决定是否仅 HTTPS 传输。
  • get_cookie_samesite():配置 SameSite 防 CSRF(Strict/Lax)。
  • get_cookie_partitioned():是否启用 Partitioned 属性(用于跨站 Cookie 隔离)。
(3) 辅助逻辑
  • should_set_cookie():决定是否设置 Set-Cookie 头(基于修改状态或 SESSION_REFRESH_EACH_REQUEST)。
  • make_null_session():生成 NullSession 实例。
  • is_null_session():检查对象是否为无效 Session。

3. 默认实现(SecureCookieSessionInterface)

(1) 安全特性

签名机制:使用 itsdangerous.URLSafeTimedSerializer

  • 支持密钥轮换(SECRET_KEY_FALLBACKS)。
  • 可配置盐值(salt)、哈希算法(如 sha1)和密钥派生方式(如 hmac)。

数据序列化:通过 TaggedJSONSerializer 处理 Python 特殊类型(如 datetime)。

(2) 工作流程

读取 Session

  • 从请求的 Cookie 中加载数据。
  • 验证签名和时间戳(防止篡改和过期会话)。
  • 失败时返回空 Session。

保存 Session

  • 若 Session 为空且被修改 → 删除 Cookie。
  • 若需更新(should_set_cookie 为 True)→ 写入签名后的数据到 Cookie。
  • 自动设置 Vary: Cookie 头以适配缓存。

(3) 配置示例

app.config.update(
    SECRET_KEY="your-secret-key",
    SESSION_COOKIE_NAME="my_session",
    SESSION_COOKIE_SECURE=True,
    SESSION_COOKIE_SAMESITE="Lax",
    PERMANENT_SESSION_LIFETIME=timedelta(days=7),
)

4. 设计思想

  • 客户端存储:Session 数据默认通过 Cookie 存储(节省服务端资源)。
  • 安全优先:所有数据签名防篡改,且支持安全相关的 Cookie 属性。
  • 灵活扩展:通过实现 SessionInterface 可轻松切换为服务端 Session(如 Redis 存储)。

常见问题

  • 密钥缺失:未设置 SECRET_KEY 时,所有 Session 操作将触发 NullSession 的异常。
  • 性能注意:Cookie 大小受限(通常不超过 4KB),复杂数据需考虑服务端存储方案。

如果需要进一步分析特定部分(如自定义 Session 存储),可以深入探讨具体实现方式。

到此这篇关于flask库中sessions.py的使用小结的文章就介绍到这了,更多相关flask sessions.py内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于flask库中sessions.py的使用小结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155500

相关文章

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

Python获取浏览器Cookies的四种方式小结

《Python获取浏览器Cookies的四种方式小结》在进行Web应用程序测试和开发时,获取浏览器Cookies是一项重要任务,本文我们介绍四种用Python获取浏览器Cookies的方式,具有一定的... 目录什么是 Cookie?1.使用Selenium库获取浏览器Cookies2.使用浏览器开发者工具

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

Spring AI使用tool Calling和MCP的示例详解

《SpringAI使用toolCalling和MCP的示例详解》SpringAI1.0.0.M6引入ToolCalling与MCP协议,提升AI与工具交互的扩展性与标准化,支持信息检索、行动执行等... 目录深入探索 Spring AI聊天接口示例Function CallingMCPSTDIOSSE结束语

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么