python-redis缓存装饰器
目录
- redis_decorator
- 安装
- 查看源代码
- 使用
- redis_decorators
- 安装
- 查看源代码
- \_\_init\_\_.py
- cacheable.py 各种可缓存的类型
- cache_element.py 缓存的元素
- caching.py 缓存主要逻辑
- 使用
- 总结
- 全部代码
- 参考
redis_decorator
安装
pip install redis_decorator
查看源代码
from io import StringIO
import pandas as pd
import json
import functoolsclass Cache:def __init__(self, redis_instance):if type(redis_instance.echo("hello")) == str:self.cache_container = redis_instanceelse:raise AttributeError("Redis instance's decode_responses must be set True. Use StrictRedis(..., decode_responses=True)")def key_generator(self, func, *args, **kwargs):return ":".join(["redis_dec", str(":".join([func.__name__, *[str(i) for i in args], str(kwargs)]))])def ttl(self, ttl=None, force_refresh=False):def enable(func):@functools.wraps(func)def func_wrapper(*args, **kwargs):target_key = self.key_generator(func, *args, **kwargs)a = self.cache_container.get(target_key)if a:return aelse:result = func(*args, **kwargs)self.cache_container.set(target_key, result, ttl)return resultreturn func_wrapperreturn enabledef delete_cache(self, func=None, *args, **kwargs):if func is None:print("Delete all the redis_dec")key = self.cache_container.scan(match="redis_dec:*")[1]elif not args and not kwargs:print("Remove every result related to this function")key = self.cache_container.scan(match=":".join(["redis_dec", func.__name__, "*"]))[1]else:key = [self.key_generator(func, *args, **kwargs)]if key:self.cache_container.delete(*key)return 0def _ser_df(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):return func(*args, **kwargs).to_csv()return func_wrapperdef _de_ser_df(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):tmp = pd.read_csv(StringIO(func(*args, **kwargs)))return tmp.set_index(tmp.columns[0])return func_wrapperdef df(self, ttl=None):def deco(func):for dec in [self._ser_df, self.ttl(ttl), self._de_ser_df]:func = dec(func)return funcreturn decodef _ser_number(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):return str(func(*args, **kwargs))return func_wrapperdef _de_ser_int(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):return int(func(*args, **kwargs))return func_wrapperdef _de_ser_float(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):return float(func(*args, **kwargs))return func_wrapperdef int(self, ttl=None):def deco(func):for dec in [self._ser_number, self.ttl(ttl), self._de_ser_int]:func = dec(func)return funcreturn decodef float(self, ttl=None):def deco(func):for dec in [self._ser_number, self.ttl(ttl), self._de_ser_float]:func = dec(func)return funcreturn decodef _ser_dict(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):return json.dumps(func(*args, **kwargs))return func_wrapperdef _de_ser_dict(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):return json.loads(func(*args, **kwargs))return func_wrapperdef dict(self, ttl=None):def deco(func):for dec in [self._ser_dict, self.ttl(ttl), self._de_ser_dict]:func = dec(func)return funcreturn decodef list(self, ttl=None):def deco(func):for dec in [self._ser_dict, self.ttl(ttl), self._de_ser_dict]:func = dec(func)return funcreturn decodef _de_ser_json(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):return json.loads(func(*args, **kwargs))return func_wrapperdef _ser_json(self, func):@functools.wraps(func)def func_wrapper(*args, **kwargs):return json.dumps(json.loads(func(*args, **kwargs)))return func_wrapperdef json(self, ttl=None):def deco(func):for dec in [self._ser_json, self.ttl(ttl), self._de_ser_json]:func = dec(func)return funcreturn decoif __name__ == '__main__':pass
- Cache类:缓存
- __init__:初始化,必须使用StrictRedis、参数decode_responses=True
- ttl:设置过期时间,单位s
- key_generator:生成key,没填写时,生成redis_dec:方法名:参数1:参数2…形式的key
- delete_cache:删除缓存,删除全部缓存、指定函数缓存、指定函数及参数缓存
- df:缓存df类型数据
- int: 缓存int类型数据
- float: 缓存float类型数据
- dict:缓存dict类型数据
- list :缓存list类型数据
- json:缓存json类型数据,和dict一样
使用
测试缓存int值
python -m unittest test.Test.test_my_int_function
测试批量删除
python -m unittest test.Test.test_delete
测试key生成与删除
python -m unittest test.Test.test_gen_key_delete
redis_decorators
安装
这里先安装一个其他人写的,体验一下
pip install redis_decorators
Successfully installed async-timeout-4.0.3 importlib-metadata-6.7.0 redis-5.0.3 redis-decorators-1.0.1 typing-extensions-4.7.1 zipp-3.15.0
注意:使用时如果报错,需要先删除__init__.py的12行
查看源代码
__init__.py
from .cache_element import CacheDateTime, CacheElement, CacheElementSingleType
from .cacheable import (Cacheable,DictCacheable,DictCacheType,DictStringCacheable,ListCacheable,ListCacheType,StringCacheable
)
from .caching import RedisCaching, build_redis_url
初始化,导入各种包
cacheable.py 各种可缓存的类型
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Dict, Generic, List, Optional, TypeVarfrom redis import RedisStoreType = TypeVar('StoreType')
ListCacheType = List[str]
DictCacheType = Dict[str, str]class Cacheable(Generic[StoreType], ABC):"""Performs caching store and fetch operations for a specific type.Subclass to define how to handle a specific type."""@abstractmethoddef store(self, client: Redis, key: str, value: StoreType) -> None:"""Store a value in cache.Args:client (Redis): Cache to store in.key (str): Name of cache value.value (StoreType): Value to store.Returns:None"""pass # pragma: nocover@abstractmethoddef fetch(self, client: Redis, key: str) -> Optional[StoreType]:"""Fetch a value from cache.Args:client (Redis): Cache to fetch from.key (str): Name of cache value.Returns:StoreType or None: Value fetched from cache or None if no value exists."""pass # pragma: nocoverclass StringCacheable(Cacheable[str]):def store(self, client: Redis, key: str, value: str):client.set(key, value)def fetch(self, client: Redis, key: str) -> Optional[str]:return client.get(key)@dataclass
class DictStringCacheable(Cacheable[str]):"""Attributes:dict_key (str): Name of hash value."""dict_key: strdef store(self, client: Redis, key: str, value: str):client.hset(key, self.dict_key, value)def fetch(self, client: Redis, key: str) -> Optional[str]:return client.hget(key, self.dict_key)class DictCacheable(Cacheable[DictCacheType]):def store(self, client: Redis, key: str, value: DictCacheType):client.hset(key, mapping=value)def fetch(self, client: Redis, key: str) -> Optional[DictCacheType]:return client.hgetall(key) or Noneclass ListCacheable(Cacheable[ListCacheType]):def store(self, client: Redis, key: str, value: ListCacheType):client.delete(key)client.rpush(key, *value)def fetch(self, client: Redis, key: str) -> Optional[ListCacheType]:return client.lrange(key, 0, -1) or None
- Cacheable类:抽象类,不可实例化。对特定类型执行缓存存储(store)和提取(fetch)操作。子类来定义如何处理特定类型。
- StringCacheable类:Cacheable子类,使用set、get处理字符串。
- DictStringCacheable类:Cacheable子类,使用hset、hget处理字典,有dict_key,有dataclass装饰,将会自动添加__init__等方法。
- DictCacheable类:Cacheable子类,使用hset、hgetall处理字典。
- ListCacheable类:Cacheable子类,使用delete、rpush、lrange处理列表。
cache_element.py 缓存的元素
from abc import ABC, abstractmethod
from dataclasses import dataclass
from datetime import datetime
from typing import Generic, Optional, TypeVarfrom redis import Redisfrom .cacheable import Cacheable, StringCacheableFetchType = TypeVar('FetchType')
StoreType = TypeVar('StoreType')class CacheElement(Generic[FetchType, StoreType], ABC):"""Get and set cache values.Attributes:cacheable (Cacheable): Instance used to store and fetch values."""cacheable: Cacheable[StoreType]def get_value(self, client: Redis, key: str) -> Optional[FetchType]:"""Returns cached value or None if no value exists."""value = self.cacheable.fetch(client, key)if value is None:return Nonereturn self.load(value)def set_value(self, client: Redis, key: str, value: FetchType) -> None:"""Set value in cache.Args:client (Redis): Cache to fetch from.key (str): Name of cache value.Returns:None"""self.cacheable.store(client, key, self.dump(value))@abstractmethoddef load(self, value: StoreType) -> FetchType:"""Load value from cache into expected Python type."""pass # pragma: nocover@abstractmethoddef dump(self, value: FetchType) -> StoreType:"""Dump value from Python type into type expected by cache."""pass # pragma: nocover@dataclass
class CacheElementSingleType(CacheElement[FetchType, FetchType]):"""A CacheElement that fetches the same type that it stores.By default, values are passed to and from cache as-is, i.e. no serializationor deserialization is performed.For example, a string can be stored and fetched without modification whereasa datetime would need to be serialized for storage and deserialized forretrieval."""cacheable: Cacheable[FetchType]def load(self, value: FetchType) -> FetchType:return valuedef dump(self, value: FetchType) -> FetchType:return value@dataclass
class CacheDateTime(CacheElement[datetime, str]):"""Store and fetch datetime values with string serialization."""cacheable: Cacheable[str] = StringCacheable()def dump(self, value: datetime) -> str:return value.isoformat()def load(self, value: str) -> datetime:return datetime.fromisoformat(value)
- CacheElement类:抽象类。缓存元素,子类实现设置和获取缓存值。
- CacheElementSingleType类:CacheElement子类,有cacheable,有dataclass装饰,自动添加__init__等方法。
- CacheDateTime类:CacheElement子类,通过字符串序列化的方式缓存日期类型,有cacheable,有dataclass装饰,自动添加__init__等方法。
caching.py 缓存主要逻辑
from datetime import timedelta
from functools import partial, update_wrapper
from typing import Any, Callable, Optional, Unionfrom redis import Redisfrom .cache_element import CacheDateTime, CacheElement, CacheElementSingleType
from .cacheable import (DictCacheable,DictCacheType,DictStringCacheable,ListCacheable,ListCacheType,StringCacheable
)class RedisCaching:"""Provides decorators for automatic caching."""cache_cls = Redis_cache_instances = {}def __init__(self, url=None, **kwargs):self._default_cache_kwargs = {'decode_responses': True, 'socket_timeout': 15}self.init(url, **kwargs)def init(self, url, **kwargs):self._url = urlself._cache_kwargs = {**self._default_cache_kwargs,**kwargs,}def get_cache(self) -> Redis:if self._url in self._cache_instances:return self._cache_instances.get(self._url)cache = self.cache_cls.from_url(self._url, **self._cache_kwargs)self._cache_instances[self._url] = cachereturn cachedef delete(self, cache_key: str):self.get_cache().delete(cache_key)def cache_value(self,cache_element: CacheElement,get_cache_key: Callable[..., str] = None,expire_in: Union[int, timedelta] = None,):"""Decorate a function to automatically cache its return value.Wrapper does two things:1. If cached value does not exist, cache the return value of the function.2. If cached value exists, return it instead of calling the function.Args:cache_element (CacheElement): Instance used to get and set cache value.get_cache_key (Callable): Function that returns name of cache value.Accepts the same arguments as the decorated function.expire_in (Union[int, timedelta]): Number of seconds until this keyexpires after being set. Can be a datetime.timedelta object.Examples:Decorate a function that returns a string:.. code-block:: python@cache.cache_string(get_cache_key=lambda arg: f'object:{arg}')def expensive_fetch_operation(arg) -> str:...return computed_valueUse `cache_key` of decorated function to set `get_cache_key`:.. code-block:: python@cache.cache_string()def expensive_fetch_operation(arg) -> str:...return computed_value@expensive_fetch_operation.cache_keydef expensive_fetch_operation_cache_key(arg) -> str:...return computed_value"""def decorator(func):return CacheValueWrapper(self, func, cache_element, get_cache_key, expire_in)return decoratordef cache_string(self, get_cache_key: Callable[..., str] = None, **kwargs):"""Decorate a function to store a string."""return self.cache_value(CacheElementSingleType[str](cacheable=StringCacheable()),get_cache_key,**kwargs,)def cache_dict(self, get_cache_key: Callable[..., str] = None, **kwargs):"""Decorate a function to store a dictionary {str: str}."""return self.cache_value(CacheElementSingleType[DictCacheType](cacheable=DictCacheable()),get_cache_key,**kwargs,)def cache_dict_string(self, dict_key: str, get_cache_key=None, **kwargs):"""Decorate a function to store a specific key inside a cached hash."""return self.cache_value(CacheElementSingleType[str](cacheable=DictStringCacheable(dict_key)),get_cache_key,**kwargs,)def cache_list(self, get_cache_key: Callable[..., str] = None, **kwargs):"""Decorate a function to store a list of strings."""return self.cache_value(CacheElementSingleType[ListCacheType](cacheable=ListCacheable()),get_cache_key,**kwargs,)def cache_datetime(self, get_cache_key: Callable[..., str] = None, **kwargs):"""Decorate a function to store a datetime."""return self.cache_value(CacheDateTime(), get_cache_key, **kwargs)class CacheValueWrapper:def __init__(self,caching: RedisCaching,func: Callable,cache_element: CacheElement,get_cache_key: Optional[Callable[..., str]] = None,expire_in: Union[int, timedelta] = None,):self._caching = cachingself._func = funcself._cache_element = cache_elementself._get_cache_key = get_cache_keyself._expire_in = expire_inupdate_wrapper(self, func)def __call__(self, *args: Any, **kwargs: Any):cache_key = self._calculate_cache_key(*args, **kwargs)value = self._cache_element.get_value(self._caching.get_cache(), cache_key)if value is None:client = self._caching.get_cache()value = self._func(*args, **kwargs)self._cache_element.set_value(client, cache_key, value)expire_in = self._calculate_expire_in(value, *args, **kwargs)if expire_in:client.expire(cache_key, expire_in)return valuedef __get__(self, instance, owner):return partial(self, instance)def cache_key(self, func):self._get_cache_key = funcreturn funcdef expire_in(self, func):self._expire_in = funcreturn funcdef _calculate_expire_in(self, value, *args, **kwargs):if callable(self._expire_in):kwargs['value'] = valuereturn self._expire_in(*args, **kwargs)return self._expire_indef _calculate_cache_key(self, *args: Any, **kwargs: Any):if self._get_cache_key is None:arg_str = ':'.join([self._func.__name__, *[str(arg) for arg in args], str(kwargs)])return ':'.join(['redis_decorators', arg_str])return self._get_cache_key(*args, **kwargs)def build_redis_url(host, password, db, use_secure=True):prefix = 'rediss' if use_secure else 'redis'if password:url = f'{prefix}://:{password}@{host}'else:url = f'{prefix}://{host}'if db:url = f'{url}/{db}'return url
-
RedisCaching类:提供自动化缓存装饰器
- get_cache方法:获取Redis实例
- delete方法:删除指定key
- cache_value:装饰器,自动缓存函数返回值
- cache_string:缓存字符串
- cache_dict:缓存字典
- cache_dict_string:
- cache_list:缓存列表
- cache_datetime:缓存日期时间
-
CacheValueWrapper类:
- cache_key:缓存key
- expire_in:过期时间
- _calculate_cache_key:如果cache_key为None时,计算key为redis_decorators:函数名:参数1:参数2…
- _calculate_expire_in:计算过期时间
-
build_redis_url:根据参数构建url
使用
缓存字符串
python -m unittest test.Test.test_my_string_function
python -m unittest test.Test.test_my_datetime_function
python -m unittest test.Test.test_my_list_function
python -m unittest test.Test.test_my_dict_function
测试删除
python -m unittest test.Test.test_delete_key
总结
redis缓存装饰器需要考虑以下几点:
- key生成:用户不指定key时需要自动生成,统一前缀方便后序更新、删除
- 指定key:用户可以指定key(redis_decorator无法指定key)
- 缓存和获取功能
- 常见类型的缓存支持
- 用户自定义类型可以继承抽象类,实现序列化和反序列化方法(redis_decorator没有)
- 指定key的更新(包没有)
- 指定或批量key的删除(redis_decorators只有删除指定key)
- 支持协程(包没有)
全部代码
main.py
from redis import StrictRedis
from redis_dec import Cache
from redis_decorators import RedisCaching
from datetime import datetime
from settings import REDIS_URLrediss = StrictRedis.from_url(REDIS_URL,decode_responses=True)
redis_cache = Cache(rediss)caching = RedisCaching(REDIS_URL)
cache = caching.get_cache() # Redis instance@redis_cache.int()
def my_int_function(a: int, b: int):print(f"my_int_function excuting with {a} {b}...")return a+b@caching.cache_string()
def my_string_function(arg1, arg2):print(f"my_string_function excuting with {arg1} {arg2}...")return str(arg1+arg2)@caching.cache_datetime()
def my_datetime_function(date):print(f"my_date_function excuting with {date}")return datetime.now()@caching.cache_list()
def my_list_function(*arg):print(f"my_list_function excuting with {arg}")return list(arg)@caching.cache_dict()
def my_dict_function(data:dict):print(f"my_dict_function excuting with {data}")return data
test.py
import unittestclass Test(unittest.TestCase):def test_gen_key_delete(self):from main import redis_cachefrom main import my_int_functionkey = redis_cache.key_generator(my_int_function,5,6)redis_cache.cache_container.delete(key)def test_my_int_function(self):from main import my_int_functionres = my_int_function(5,6)print(res)def test_delete(self):from main import redis_cachefrom main import my_int_functionres = redis_cache.delete_cache(func=my_int_function)print(res)def test_my_string_function(self):from main import my_string_functionres = my_string_function(arg1=1,arg2=2)print(res)def test_my_datetime_function(self):from main import my_datetime_functionres = my_datetime_function("now")print(res)def test_my_list_function(self):from main import my_list_functionres = my_list_function(4,5,6)print(res)def test_my_dict_function(self):from main import my_dict_functionres = my_dict_function({"1":1})print(res)def test_delete_key(self):from main import cachingfrom typing import Anyfunc_name = "my_datetime_function"def _calculate_cache_key(*args: Any, **kwargs: Any):arg_str = ':'.join([func_name, *[str(arg) for arg in args], str(kwargs)])return ':'.join(['redis_decorators', arg_str])caching.delete(_calculate_cache_key("now"))
参考
redis-python客户端官方文档
pypi-redis-decorator
python3-abc包
python3-dataclasses包
pypi-redis-decorators
github-python-redis-decorators
相关文章:

python-redis缓存装饰器
目录 redis_decorator安装查看源代码使用 redis_decorators安装查看源代码\_\_init\_\_.pycacheable.py 各种可缓存的类型cache_element.py 缓存的元素caching.py 缓存主要逻辑 使用 总结全部代码参考 redis_decorator 安装 pip install redis_decorator查看源代码 from io …...

每个私域运营者都必须掌握的 5 大关键流量运营核心打法!
很多人觉得私域运营比较简单,只是运营的事情,但事实并非如此,私域运营体系非常大,包含了公私域联动、品牌运营、品类战略,它是一个自上而下,由内到外的系统化工程。 很多人天天在想着如何引流拓客…...
蓝桥杯--平均
在编程竞赛,尤其是参与蓝桥杯的过程中,遇到各种问题需求是家常便饭。最近,我遇到了一个非常有趣且颇具挑战性的算法问题。问题描述如下:对于一个长度为n的数组(n是10的倍数),数组中的每个元素均…...

未来已来:科技驱动的教育变革
我们的基础教育数百年来一成不变。学生们齐聚在一个物理空间,听老师现场授课。每节课时长和节奏几乎一致,严格按照课表进行。老师就像“讲台上的圣人”。这种模式千篇一律,并不适用于所有人。学生遇到不懂的问题,只能自己摸索或者…...

【蓝桥杯每日一题】填充颜色超详细解释!!!
为了让蓝桥杯不变成蓝桥悲,我决定在舒适的周日再来一道题。 例: 输入: 6 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1 输出: 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 2 2 1 1 1 2 2 2 1 1 2 2 2 2 1 1…...
VSCODE的常用插件
1、中文设置 (1)搜索 chinese Chinese (Simplified) Language Pack for Visual Studio Code C/C Extension Pack (2)配置 通过使用“Configure Display Language”命令显式设置 VS Code 显示语言,可以替代默认 UI…...
Oracle常用DBA相关语句
Oracle常用DBA相关语句 1 表空间1.1 创建表空间1.2 删除表空间1.3 收缩表空间1.4 新增表空间文件1.5 查看表空间使用情况1.6 查看表所占用的空间大小 2 表分区2.1 查询表分区的创建情况2.2 查询表时指定分区 3 用户3.1 创建用户3.2 给用户赋权限3.3 删除用户 4 导入导出4.1 导入…...
JavaScript 入门指南(一)简介及基础语法
JavaScript 简介 JavaScript,简称 js,是一种基于对象(object-based)和事件驱动(Event Driven)的简单的并具有安全性能的脚本语言。 JavaScript 特性 JavaScript 是解释性语言,而不是编译性语言…...
UbuntuServer22.04配置静态IP地址
查看网络配置文件 使用命令, 查看网络配置文件 ls -l /etc/netplan/输出如下(文件名可能不同, 以实际查询为准) -rw------- 1 root root 191 Mar 17 03:30 00-installer-config.yaml编辑文件即可修改网络配置 sudo vim /etc/netplan/00-installer-config.yaml配…...
vue3 打印局部网页、网页下载为图片、下载为pdf-自动分页,几行代码搞定
经常有一些需求,要将网页保存为一张图片,感觉异常困难,这里发现一个简单的办法。 这么简单,直接一句哇塞,老板:马上完成任务。 先安装几个依赖 npm i howuse html2canvas jspdf 下载图片代码 <button …...

力扣hot100:34. 在排序数组中查找元素的第一个和最后一个位置(二分查找的理解)
我们知道使用二分查找能找到值所在的位置。假如我们在找到值后仍然不断的更新指针会发生什么?我们可以利用这一点来找到最左边的以及最右边的值。 如果当nums[mid]target时,使得 rightmid-1,那么最终会使得target在right的右边。 如果当nums[…...

几何相互作用GNN预测3D-PLA
预测PLA是药物发现中的核心问题。最近的进展显示了将ML应用于PLA预测的巨大潜力。然而,它们大多忽略了复合物的3D结构和蛋白质与配体之间的物理相互作用,而这对于理解结合机制至关重要。作者提出了一种结合3D结构和物理相互作用的几何相互作用图神经网络GIGN,用于预测蛋白质…...

2024最新版使用PyCharm搭建Anaconda
2024最新版使用PyCharm搭建Anaconda 因为pycharm自带的包不全,或者下载的时候比较慢,所以我们直接用anaconda的包,毕竟我们以后还会学到很多的包,不多说,直接开干! 一、下载Pycharm、Anacoda pycharm中文网…...
前台于后台项目
一:技术栈 前台:vue3element plus 后台:reactant desgin 二:项目中的问题: 多人协同开发导致样式冲突 ui框架中组件的使用 ui框架中组件样式的修改 精度缺失问题 框架的使用 三:解决方案: …...

Magical Combat VFX
这个包包含30个可供游戏使用的VFX,有各种口味,为您的游戏增添趣味! 所有VFX都经过了很好的优化,可以在所有平台上使用。 这个包特别有一堆闪电魔法,有两种主要的变体,一种是深色的,另一种是浅色的。但它也提供了一系列其他视觉效果,如神圣咒语、音乐主题等等! 我们提供…...

hadoop伪分布式环境搭建详解
(操作系统是centos7) 1.更改主机名,设置与ip 的映射关系 hostname //查看主机名 vim /etc/hostname //将里面的主机名更改为master vim /etc/hosts //将127.0.0.1后面的主机名更改为master,在后面加入一行IP地址与主机名之间的…...

day12-SpringBootWeb 登录认证
一、登录功能 Slf4j RestController public class LoginController {Autowiredprivate EmpService empService;PostMapping("/login")public Result login(RequestBody Emp emp){log.info("员工登录: {}", emp);Emp e empService.login(emp);//登录失败, …...

内外网数据单向导入导出 如何提升效率确保安全性?
金融、证券、税务、海关、军工、国央企、生物医药等涉密行业,为了保护内部的核心数据,都会将网络进行物理隔离,网络物理隔离主要是采用隔离硬件设备,在人工或者软件的控制下,进行内外网的切换和数据交换。 传统的内外网…...
Spring核心方法:Refresh全解(WebMVC如何装配、关联)
Spring核心方法:Refresh全解(WebMVC如何装配、关联) 这里是一个表格,列出了Spring容器刷新过程中执行的方法以及它们的作用: 方法名称描述prepareRefresh()初始化一些属性和状态,例如启动时间戳、活动标志、环境变量等。obtainF…...

TCP:三次握手四次挥手及相关问题:
连接—三次握手: 流程图: 过程详解: 客户端(connect)连接服务器(listen) Client将标志位SYN置为1,随机产生一个值seqx, 并将该数据包发送给Server, Client进入SYN_ SENT状态,等待Server确认。Server收到数据包后由标…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...

【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...