Python快速入门专业版(二十八):函数参数进阶:默认参数与可变参数(*args/**kwargs)

在这里插入图片描述

目录

  • 一、默认参数:给函数参数设置“默认值”
    • 1. 基本语法与使用示例
      • 示例1:带默认参数的乘法函数
    • 2. 默认参数的核心规则:必须放在非默认参数之后
      • 示例2:默认参数位置错误(报错)
    • 3. 默认参数的“可变对象陷阱”:默认值只初始化一次
      • 示例3:默认参数为可变对象(列表)的陷阱
      • 解决方案:默认值用None,在函数内初始化可变对象
    • 4. 默认参数的适用场景
  • 二、可变参数*args:接收任意个位置参数
    • 1. 基本语法与工作原理
      • 示例4:用*args接收任意个位置参数
    • 2. 实战:用*args实现自定义求和函数
      • 示例5:自定义求和函数(支持任意个数相加)
    • 3. *args与普通参数的混合使用
      • 示例6:混合使用普通参数和*args
  • 三、可变参数**kwargs:接收任意个关键字参数
    • 1. 基本语法与工作原理
      • 示例7:用**kwargs接收任意个关键字参数
    • 2. 实战:用**kwargs处理用户动态属性
      • 示例8:处理用户动态属性的函数
    • 3. **kwargs与其他参数的混合使用
      • 示例9:所有参数类型的混合使用(正确顺序)
      • 示例10:** kwargs位置错误(报错)
  • 四、*args与**kwargs的高级应用:参数转发
    • 1. 封装函数时的参数转发
      • 示例11:封装print函数,转发所有参数
    • 2. 装饰器中的参数转发
      • 示例12:用装饰器记录函数调用日志(参数转发)
  • 五、*args与**kwargs的命名规范与最佳实践
    • 1. 命名规范
    • 2. 最佳实践
      • 实践1:优先明确参数,再用可变参数
      • 实践2:限制*args和**kwargs的使用场景
      • 实践3:为可变参数添加文档说明
  • 六、综合案例:灵活的数据分析函数
    • 1. 案例代码实现
    • 2. 案例解析
  • 七、总结与提升
    • 进阶练习

在函数参数的世界里,基础的位置参数和关键字参数只是起点。当面对更复杂的场景——比如希望函数某些参数有默认值、需要处理不确定数量的输入,或者灵活传递参数给其他函数时,默认参数和可变参数(*args/**kwargs)就成了不可或缺的工具。它们不仅能让函数更灵活、更易用,还能大幅提升代码的复用性和扩展性。

本文将深入解析默认参数的设计逻辑与常见陷阱,系统讲解*args和**kwargs的工作原理与使用场景,通过“动态求和”“灵活配置”等实战案例,帮助你掌握这些进阶参数的精髓,让函数设计从“满足基本需求”升级到“应对复杂场景”。

一、默认参数:给函数参数设置“默认值”

在很多场景下,函数的某些参数在大多数情况下取值固定,只有少数情况需要修改。例如:计算商品总价时,税率通常固定为13%;发送消息时,默认接收者是系统管理员。这时,默认参数就能派上用场——在函数定义时为参数指定默认值,调用时可省略该参数,使用默认值;若有特殊需求,再显式传递新值覆盖默认值。

1. 基本语法与使用示例

默认参数的定义方式非常简单:在函数形参后加=默认值即可。调用函数时,若不传递该参数,则使用默认值;若传递,则使用新值。

示例1:带默认参数的乘法函数

def multiply(a, b=10):"""计算a乘以b,b的默认值为10"""return a * b# 调用时省略b,使用默认值10
result1 = multiply(5)  # 等价于multiply(5, 10)
print(f"5 × 10(默认) = {result1}")  # 输出:5 × 10(默认) = 50# 调用时传递b,覆盖默认值
result2 = multiply(5, 3)
print(f"5 × 3(自定义) = {result2}")  # 输出:5 × 3(自定义) = 15

解析

  • 函数定义def multiply(a, b=10)中,b是默认参数,默认值为10;a是非默认参数(必须传递的参数)。
  • 调用multiply(5)时,只传递了a=5b自动使用默认值10,计算5×10=50
  • 调用multiply(5, 3)时,b=3覆盖默认值,计算5×3=15

这种设计让函数在“大多数常规场景”下调用更简洁,同时保留了“特殊场景”下的灵活性。

2. 默认参数的核心规则:必须放在非默认参数之后

Python规定:所有默认参数必须位于非默认参数的后面。这是因为函数解析参数时,会先处理位置参数,再处理默认参数。若默认参数放在前面,会导致参数绑定混乱。

示例2:默认参数位置错误(报错)

# 错误:默认参数b放在非默认参数a前面
def multiply(b=10, a):return a * b

报错信息:

SyntaxError: non-default argument follows default argument

解析:错误原因是“非默认参数跟在默认参数之后”。假设允许这种定义,调用multiply(5)时,解释器无法判断5是给b(默认参数)还是a(非默认参数),导致歧义。因此Python从语法层面禁止了这种写法。

正确的做法是将所有非默认参数放在前面,默认参数放在后面,例如def func(a, b, c=0, d=1): ...

3. 默认参数的“可变对象陷阱”:默认值只初始化一次

默认参数的默认值在函数定义时就会被初始化,而非每次调用时重新生成。这对整数、字符串等不可变对象没问题,但对列表、字典等可变对象可能导致意外结果。

示例3:默认参数为可变对象(列表)的陷阱

def add_item(item, items=[]):"""向列表中添加元素,默认列表为空"""items.append(item)return items# 第一次调用:预期返回[1]
print(add_item(1))  # 输出:[1]# 第二次调用:预期返回[2],实际返回[1, 2]
print(add_item(2))  # 输出:[1, 2]

解析

  • 函数定义时,items=[]创建了一个空列表,这个列表对象在内存中只会被创建一次。
  • 第一次调用add_item(1)时,items指向这个列表,添加1后变为[1]
  • 第二次调用时,items仍然指向同一个列表(而非重新创建空列表),添加2后变为[1, 2],与预期不符。

这就是“可变对象陷阱”——默认参数为可变对象时,多次调用会共享同一个对象,导致状态累积。

解决方案:默认值用None,在函数内初始化可变对象

def add_item(item, items=None):"""修复可变对象陷阱:用None作为默认值,在函数内初始化列表"""if items is None:items = []  # 每次调用时重新创建空列表items.append(item)return items# 多次调用结果符合预期
print(add_item(1))  # 输出:[1]
print(add_item(2))  # 输出:[2]

解析:将默认值设为None(不可变对象),每次调用时若未传递items,则在函数内重新创建空列表,避免了多次调用共享同一个列表的问题。这是处理默认参数为可变对象的标准做法。

4. 默认参数的适用场景

默认参数非常适合以下场景:

  • 常用参数固定值:如def connect(host, port=8080),端口号8080是最常用的,无需每次指定。
  • 可选功能开关:如def download(url, proxy=False)proxy=False表示默认不使用代理,需要时传递proxy=True
  • 参数兼容性:当函数需要新增参数时,给新参数设置默认值,避免影响旧的调用代码(向后兼容)。

二、可变参数*args:接收任意个位置参数

在实际开发中,我们经常会遇到“函数需要处理的参数数量不确定”的情况。例如:实现一个求和函数,支持2个数相加、3个数相加,甚至10个数相加;定义一个打印函数,能接收任意个待打印的对象。这时,可变参数*args就能解决这个问题——它可以接收任意数量的位置参数,并将它们封装成一个元组。

1. 基本语法与工作原理

*args的语法是在参数名前加*(星号),表示该参数是可变位置参数。调用函数时,传递的所有位置参数都会被收集到args中,作为一个元组存在。

示例4:用*args接收任意个位置参数

def print_args(*args):"""打印接收的所有位置参数"""print("参数类型:", type(args))  # 输出:<class 'tuple'>print("参数值:", args)# 传递不同数量的位置参数
print_args(1, 2, 3)          # 输出:参数值:(1, 2, 3)
print_args("a", "b")         # 输出:参数值:('a', 'b')
print_args(True, 3.14, "hello")  # 输出:参数值:(True, 3.14, 'hello')
print_args()                 # 输出:参数值:()(空元组)

解析

  • 函数定义def print_args(*args)中,*args表示“收集所有位置参数”。
  • 无论传递0个、1个还是多个位置参数,args都会将它们打包成元组(即使只有一个参数,也是元组(x,))。
  • 若未传递位置参数,args是一个空元组(),不会报错。

这种特性让函数能灵活处理“参数数量不确定”的场景,无需提前定义固定数量的形参。

2. 实战:用*args实现自定义求和函数

最典型的*args应用是实现支持任意个数相加的求和函数,替代固定参数的add(a, b)add(a, b, c)等繁琐定义。

示例5:自定义求和函数(支持任意个数相加)

def custom_sum(*args):"""计算任意个数字的和"""# 处理无参数的情况if not args:  # 判断元组是否为空return 0total = 0for num in args:  # 遍历元组中的所有参数# 只累加数字类型,忽略非数字(可选逻辑)if isinstance(num, (int, float)):total += numelse:print(f"警告:{num}不是数字,已忽略")return total# 测试不同数量和类型的参数
print("求和结果:", custom_sum(1, 2, 3))  # 输出:6
print("求和结果:", custom_sum(10, 20, 30, 40))  # 输出:100
print("求和结果:", custom_sum(3.14, 2.71))  # 输出:5.85
print("求和结果:", custom_sum(5, "a", 3))  # 输出警告,结果:8
print("求和结果:", custom_sum())  # 输出:0

解析

  • *args收集所有传递的位置参数(如1,2,3),形成元组(1,2,3)
  • 函数通过遍历元组args,累加所有数字类型的元素,实现“任意个数求和”。
  • 增加了对非数字参数的处理(忽略并警告)和无参数情况的兼容(返回0),让函数更健壮。

相比固定参数的实现(如def sum(a, b, c=0, d=0): ...),*args版本的扩展性更好——无论需要加多少个数,函数定义都无需修改。

3. *args与普通参数的混合使用

*args可以与普通参数(位置参数、默认参数)混合使用,但*args必须放在普通位置参数之后、默认参数之前,遵循“位置参数→*args→默认参数”的顺序。

示例6:混合使用普通参数和*args

def func(a, b, *args, c=0):"""普通参数a、b → *args → 默认参数c"""print(f"a={a}, b={b}, args={args}, c={c}")# 调用:a和b必须传递,args接收剩余位置参数,c可选
func(1, 2)  # 输出:a=1, b=2, args=(), c=0
func(1, 2, 3, 4)  # 输出:a=1, b=2, args=(3, 4), c=0
func(1, 2, 3, 4, c=5)  # 输出:a=1, b=2, args=(3, 4), c=5

解析

  • 前两个参数ab是普通位置参数,必须传递。
  • *args接收剩余的位置参数(如3,4被收集为(3,4))。
  • 默认参数c放在最后,可省略或通过关键字传递。

这种混合方式既能保证核心参数必须传递,又能灵活接收额外的位置参数,适合“基础参数固定+附加参数灵活”的场景。

三、可变参数**kwargs:接收任意个关键字参数

*args解决了“任意个位置参数”的问题,但无法处理“任意个关键字参数”。例如:定义一个函数,需要接收用户的任意属性(姓名、年龄、性别、职业等,数量不确定);封装一个API调用函数,需要支持接口的所有可选参数(格式、页码、筛选条件等)。这时,** 可变参数kwargs就派上用场了——它可以接收任意数量的关键字参数,并将它们封装成一个字典。

1. 基本语法与工作原理

**kwargs的语法是在参数名前加**(两个星号),表示该参数是可变关键字参数。调用函数时,传递的所有关键字参数都会被收集到kwargs中,作为一个字典存在(键是参数名,值是参数值)。

示例7:用**kwargs接收任意个关键字参数

def print_kwargs(**kwargs):"""打印接收的所有关键字参数"""print("参数类型:", type(kwargs))  # 输出:<class 'dict'>print("参数值:", kwargs)# 传递不同数量的关键字参数
print_kwargs(name="小明", age=20)  # 输出:{'name': '小明', 'age': 20}
print_kwargs(city="北京", temperature=25)  # 输出:{'city': '北京', 'temperature': 25}
print_kwargs()  # 输出:{}(空字典)

解析

  • 函数定义def print_kwargs(**kwargs)中,**kwargs表示“收集所有关键字参数”。
  • 无论传递0个、1个还是多个关键字参数,kwargs都会将它们打包成字典(键是参数名,值是参数值)。
  • 若未传递关键字参数,kwargs是一个空字典{},不会报错。

**kwargs的灵活性在于:函数无需提前知道会接收哪些关键字参数,完全由调用者决定,适合处理“动态属性”或“可选配置”。

2. 实战:用**kwargs处理用户动态属性

假设需要定义一个函数,打印用户的信息,但用户属性不固定(可能有姓名、年龄、性别,也可能有职业、爱好等)。用**kwargs可以轻松实现这一需求。

示例8:处理用户动态属性的函数

def print_user_attributes(** kwargs):"""打印用户的任意属性(关键字参数形式传递)"""if not kwargs:print("没有提供用户属性")returnprint("用户属性:")for key, value in kwargs.items():  # 遍历字典中的键值对print(f"- {key}{value}")# 传递不同的用户属性
print_user_attributes(name="小红", age=18, gender="女", hobby="读书")
# 输出:
# 用户属性:
# - name:小红
# - age:18
# - gender:女
# - hobby:读书print_user_attributes(name="小刚", occupation="学生")
# 输出:
# 用户属性:
# - name:小刚
# - occupation:学生print_user_attributes()  # 输出:没有提供用户属性

解析

  • 调用者可以传递任意数量、任意名称的关键字参数(如nameagehobby等)。
  • 函数通过遍历字典kwargs,打印所有属性,无需提前定义形参。
  • 增加了对空参数的处理,让函数更友好。

这种方式特别适合处理“属性不固定”的对象,如用户信息、商品配置、API参数等,避免函数定义因参数过多而臃肿。

3. **kwargs与其他参数的混合使用

**kwargs可以与普通参数、*args混合使用,但其位置有严格限制:** 必须放在所有参数的最后**,遵循“位置参数→*args→默认参数→**kwargs”的顺序。

示例9:所有参数类型的混合使用(正确顺序)

def func(a, b, *args, c=0, **kwargs):"""完整参数顺序:位置参数→*args→默认参数→** kwargs"""print(f"a={a}, b={b}")print(f"args={args}, c={c}")print(f"kwargs={kwargs}")# 调用示例
func(1, 2, 3, 4, c=5, x=6, y=7)

输出结果:

a=1, b=2
args=(3, 4), c=5
kwargs={'x': 6, 'y': 7}

解析

  • 位置参数a=1b=2被优先处理。
  • 剩余位置参数3,4*args收集为(3,4)
  • 默认参数c被关键字参数c=5覆盖。
  • 最后,额外的关键字参数x=6y=7**kwargs收集为{'x':6, 'y':7}

示例10:** kwargs位置错误(报错)

# 错误:**kwargs放在其他参数前面
def func(** kwargs, a, b):pass

报错信息:

SyntaxError: invalid parameter name: '**kwargs'

解析**kwargs必须放在所有参数的最后,因为它需要收集“剩余的所有关键字参数”,若前面还有未处理的参数,会导致参数解析混乱。

四、*args与**kwargs的高级应用:参数转发

*args**kwargs的一个强大用途是**“参数转发”**——将一个函数接收的参数原封不动地传递给另一个函数。这在封装函数、编写装饰器等场景中非常有用,能大幅减少代码冗余。

1. 封装函数时的参数转发

假设我们需要封装Python内置的print函数,增加“打印前先输出分隔线”的功能,但又希望保留print函数的所有参数(如sepend等)。用*args**kwargs可以轻松实现,无需重复定义print的所有参数。

示例11:封装print函数,转发所有参数

def my_print(*args, **kwargs):"""封装print函数,先打印分隔线,再转发所有参数给print"""print("-" * 30)  # 新增功能:打印分隔线print(*args, **kwargs)  # 转发所有参数给内置print# 调用my_print,支持print的所有参数
my_print("Hello, World!")  # 基本用法
my_print(1, 2, 3, sep=" | ")  # 使用sep参数
my_print("结束", end="\n\n")  # 使用end参数

输出结果:

------------------------------
Hello, World!
------------------------------
1 | 2 | 3
------------------------------
结束

解析

  • my_print*args接收所有位置参数(如"Hello, World!"1,2,3),**kwargs接收所有关键字参数(如sep=" | "end="\n\n")。
  • 通过print(*args, **kwargs)将参数转发给内置print函数,***在这里的作用是“解包”(将元组解为位置参数,字典解为关键字参数)。
  • 无需知道print函数的具体参数,就能完整保留其功能,实现灵活封装。

2. 装饰器中的参数转发

装饰器(用于增强函数功能的函数)是*args**kwargs的典型应用场景。装饰器需要接收被装饰函数的所有参数,并传递给原函数,而*args**kwargs能完美适配任意参数列表的函数。

示例12:用装饰器记录函数调用日志(参数转发)

def log_call(func):"""装饰器:记录函数调用的参数和返回值"""def wrapper(*args, **kwargs):# 记录调用参数print(f"调用函数:{func.__name__}")print(f"位置参数:{args}")print(f"关键字参数:{kwargs}")# 调用原函数,转发所有参数result = func(*args, **kwargs)# 记录返回值print(f"返回值:{result}\n")return resultreturn wrapper# 用装饰器增强函数
@log_call
def add(a, b):return a + b@log_call
def greet(name, message="Hello"):return f"{message}, {name}!"# 调用被装饰的函数
add(3, 5)
greet("小明", message="你好")

输出结果:

调用函数:add
位置参数:(3, 5)
关键字参数:{}
返回值:8调用函数:greet
位置参数:('小明',)
关键字参数:{'message': '你好'}
返回值:你好, 小明!

解析

  • 装饰器log_call中的wrapper函数用*args**kwargs接收任意参数,无论被装饰的函数(addgreet)有多少参数、是什么类型,都能兼容。
  • 通过func(*args, **kwargs)将参数转发给原函数,确保原函数正常执行。
  • 这种方式让装饰器具有通用性,可应用于任何函数,无需针对不同参数列表修改装饰器代码。

五、*args与**kwargs的命名规范与最佳实践

虽然*args**kwargs中的argskwargs只是约定俗成的名称(可以换成其他名字,如*params**kwargs_dict),但遵循这些规范能让代码更易读——其他开发者看到*args就知道是“可变位置参数”,看到**kwargs就知道是“可变关键字参数”。

1. 命名规范

  • *argsargs是“arguments”的缩写,代表“位置参数的集合”。
  • **kwargskwargs是“keyword arguments”的缩写,代表“关键字参数的集合”。
  • 尽量使用默认名称,避免自定义名称(如*my_args),除非有特殊理由。

2. 最佳实践

实践1:优先明确参数,再用可变参数

不要过度依赖*args**kwargs。如果函数参数数量和名称是确定的,优先使用普通参数(更清晰);只有在参数不确定时,才使用可变参数。

反例:参数明确却滥用*args

# 不好:明明只需要a和b,却用*args
def add(*args):return args[0] + args[1]# 好:明确参数更清晰
def add(a, b):return a + b

实践2:限制*args和**kwargs的使用场景

*args适合:

  • 处理数量不确定的同类型参数(如求和、求最大值)。
  • 转发位置参数给其他函数。

**kwargs适合:

  • 处理动态属性或配置(如用户信息、API参数)。
  • 转发关键字参数给其他函数。

实践3:为可变参数添加文档说明

由于*args**kwargs的参数不明确,必须在文档字符串中说明其含义和预期类型,帮助使用者正确传递参数。

def send_request(url, *args, **kwargs):"""发送HTTP请求参数:url (str):请求URL*args:传递给requests.get的额外位置参数**kwargs:传递给requests.get的额外关键字参数(如headers、timeout等)"""import requestsreturn requests.get(url, *args, **kwargs)

六、综合案例:灵活的数据分析函数

我们通过一个“灵活的数据分析函数”案例,综合应用默认参数、*args**kwargs,实现以下功能:

  • 计算多个数据列的平均值(支持任意列,用*args接收)。
  • 提供默认的精度设置(保留2位小数,用默认参数)。
  • 支持额外的分析选项(如排序、过滤,用**kwargs接收)。

1. 案例代码实现

def custom_sum(*args):"""计算任意个数字的和"""# 处理无参数的情况if not args:  # 判断元组是否为空return 0total = 0for num in args:  # 遍历元组中的所有参数# 只累加数字类型,忽略非数字(可选逻辑)if isinstance(num, (int, float)):total += numelse:print(f"警告:{num}不是数字,已忽略")return total# 测试不同数量和类型的参数
print("求和结果:", custom_sum(1, 2, 3))  # 输出:6
print("求和结果:", custom_sum(10, 20, 30, 40))  # 输出:100
print("求和结果:", custom_sum(3.14, 2.71))  # 输出:5.85
print("求和结果:", custom_sum(5, "a", 3))  # 输出警告,结果:8
print("求和结果:", custom_sum())  # 输出:0

2. 案例解析

-*columns的作用:接收任意数量的列名(如'math''english'),若未传递则分析所有列,灵活支持不同的分析需求。

  • 默认参数precision:默认保留2位小数,调用时可通过precision=1修改,兼顾默认行为和灵活性。
  • **kwargs的作用:接收额外选项(如sort=Truefilter_min=90),无需提前定义所有可能的选项,让函数易于扩展(后续可新增filter_maxgroup等选项,无需修改函数参数列表)。

运行结果展示了函数的灵活性:既能处理简单分析,也能支持复杂配置,充分体现了默认参数和可变参数的优势。

七、总结与提升

默认参数和可变参数(*args/**kwargs)是Python函数参数体系的重要扩展,它们让函数从“固定输入”走向“灵活适配”:

  • 默认参数:为参数设置默认值,简化常规调用,语法def func(a, b=10),注意必须放在非默认参数后,避免使用可变对象作为默认值。
  • *args:收集任意个位置参数为元组,解决“参数数量不确定”问题,适合处理同类型可变输入或转发位置参数。
  • **kwargs:收集任意个关键字参数为字典,适合处理动态属性或转发关键字参数,必须放在所有参数最后。

这些参数的核心价值在于提升函数的灵活性和复用性,尤其在封装函数、编写通用工具或处理动态数据时不可或缺。

进阶练习

  1. 实现一个merge_dicts函数,接收任意个字典(*args),返回一个合并后的字典(后面的字典覆盖前面的同名键)。
  2. 改进前面的custom_sum函数,支持关键字参数ignore_negative(默认False),当为True时忽略负数。
  3. 编写一个装饰器validate_params,用于检查被装饰函数的参数是否符合指定规则(如age必须大于0),通过**kwargs接收规则配置。

通过这些练习,你将能更深入地理解这些参数的应用场景,让函数设计更贴近实际开发需求。记住:** 好的参数设计,能让函数既易用又强大**。

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

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

相关文章

FreeRTOS 知识点

一、配置过程二、基本知识点2.1 抢占优先级和响应优先级在 FreeRTOS 中&#xff0c;任务的调度方式主要有 ​​抢占式&#xff08;Preemptive&#xff09;​​ 和 ​​协作式&#xff08;Cooperative&#xff09;​​ 两种模式&#xff0c;它们的核心区别在于 ​​任务如何释放…

SQL注入漏洞手动测试详细过程

这是一次详细的、基于真实手动测试思维的SQL注入漏洞测试过程记录。我们将以一个假设的Web应用程序为例&#xff0c;进行逐步探测和利用。测试目标假设我们正在测试一个名为 example.com 的电商网站&#xff0c;其有一个查看商品详情的页面&#xff0c;URL 为&#xff1a; http…

机器人控制器开发(通讯——ros话题转为websocket)

1 为什么要实现ROS话题转WebSocket 主要有如下5个优点&#xff1a;跨平台通信需求 WebSocket作为一种标准的Web通信协议&#xff0c;允许任何支持WebSocket的客户端&#xff08;网页、移动应用、其他系统&#xff09;与ROS机器人进行实时通信&#xff0c;打破了ROS传统通信方式…

SQL-字符串函数、数值函数、日期函数

字符串函数1. 字符串拼接concat-- 拼接字符串hello和mysql&#xff0c;结果为hellomysql -- 格式&#xff1a;concat(str1, str2, ...)&#xff1a;拼接多个字符串 select concat(hello, mysql);注意事项&#xff1a;若任一参数为null&#xff0c;结果为null&#xff08;如conc…

JAVA高级工程师--Redis持久化详细版

一、Redis DBRedis 数据库的数量在单机和集群模式下有根本性的区别。1. 单机模式 (Standalone)在单机模式下&#xff0c;Redis 默认提供 16 个逻辑数据库&#xff0c;索引编号为 0 到 15。选择数据库&#xff1a; 使用 SELECT <index> 命令进行切换。例如&#xff0c;SE…

hexo文章

文章目录Tag的使用勾选框图片的组合站内文章引用注意&#xff1a;1、关于中括号的问题目录总结 Tag的使用 在 markdown 中加入如下的代码来使用便签&#xff1a; {% note success %} 文字 或者 markdown 均可 {% endnote %}或者使用 HTML 形式&#xff1a; <p class&quo…

技术面:Spring (bean的生命周期、创建方式、注入方式、作用域)

Spring Bean的生命周期是什么样的&#xff1f; 在Spring容器里一个Bean的从创建到销毁一般都是经历了以下几个阶段&#xff1a; 定义阶段&#xff08;Bean元信息配置&#xff09;>实例化阶段&#xff08;创建Bean对象&#xff09;>初始化阶段&#xff08;执行初始化逻辑&…

SpringSecurity的应用

官方文档 一、核心能力 1.1 身份认证 (Authentication) - “你是谁&#xff1f;” 多种认证方式&#xff1a;支持几乎所有主流认证方案&#xff0c;如表单登录&#xff08;Username/Password&#xff09;、HTTP Basic、HTTP Digest、OAuth 2.0、OIDC (OpenID Connect)、SAML …

跨境云手机与传统手机的不同之处

传统手机主要满足个人日常生活中的通讯、娱乐、办公等基础需求&#xff0c;比如用于日常打电话联系亲朋好友&#xff0c;闲暇时刷短视频、玩本地安装的游戏&#xff0c;或者简单处理一些文档、邮件等办公事务。跨境云手机主要是侧重于跨境业务场景&#xff0c;对于从事跨境电商…

MemGPT: Towards LLMs as Operating Systems

1 MemGPT: Towards LLMs as Operating Systems 论文地址&#xff1a;MemGPT: Towards LLMs as Operating Systems 代码地址&#xff1a;https://github.com/letta-ai/letta 1.1 MemGPT MemGPT&#xff08;MemoryGPT&#xff09;借鉴传统操作系统的分层内存管理思想&#xff08;…

MICAPS:气象信息综合分析与处理系统概述

1.概述 说明:Meteorological Information Comprehensive Analysis and Process System 中文意思:气象信息综合分析处理系统。它是中国气象局开发的一套气象数据分析、处理和可视化系统,用于气象资料的收集、整理、分析和发布。 2.MICAPS 的用途 说明: 数据收集:接收来自…

MySQL-day2_02

MySQL-day2&#xff08;四&#xff09;排序&#xff08;五&#xff09;聚合函数一、count 总记录数二、max 最大值三、min 最小值四、sum 求和五、avg 平均值&#xff08;六&#xff09;数据分组一、分组二、分组后的数据筛选&#xff08;七&#xff09;数据分页显示一、获取部…

HarmonyOS应用开发:深入ArkUI声明式开发范式与最佳实践

HarmonyOS应用开发&#xff1a;深入ArkUI声明式开发范式与最佳实践 引言 随着HarmonyOS 4.0的发布及API 12的推出&#xff0c;华为的分布式操作系统进入了全新的发展阶段。ArkUI作为HarmonyOS应用开发的核心框架&#xff0c;其声明式开发范式&#xff08;Declarative Paradigm&…

Claude-Flow AI协同开发:钩子系统与 GitHub 集成

5.1 思维认知框架&#xff1a;从“开发助手”到“DevOps 智能体” 在此之前&#xff0c;我们将 Claude-Flow 视为一个强大的 “开发助手 (Development Assistant)” &#xff0c;它在编码、测试、重构等环节为我们提供支持。现在&#xff0c;我们需要再次进行思维升级&#xff…

DigitalOcean Kubernetes 现已支持 Gateway API 托管服务

在 DigitalOcean Kubernetes 集群中管理流量&#xff0c;一直以来主要依赖 Ingress。虽然能满足基本需求&#xff0c;但在灵活性、角色分离和高级路由方面仍存在局限。今天&#xff0c;我们很高兴迎来新的改变。 我们正式宣布&#xff0c;Kubernetes Gateway API 托管服务现已…

聚铭网络入选数世咨询《中国数字安全价值图谱》“日志审计”推荐企业

近日&#xff0c;国内知名数字安全咨询机构数世咨询正式发布《中国数字安全价值图谱》。聚铭网络凭借领先的技术实力与出色的市场表现&#xff0c;成功入选“日志审计”领域重点推荐企业&#xff0c;彰显了在该赛道的专业认可与品牌影响力。关于《中国数字安全价值图谱》 在当下…

豆包、Kimi、通义千问、DeepSeek、Gamma、墨刀 AI”六款主流大模型(或 AI 平台)生成 PPT 的完整流程

、先厘清 3 个概念&#xff0c;少走弯路大模型 ≠ PPT 软件豆包、Kimi、通义千问、DeepSeek 本身只负责“出大纲/出文案”&#xff0c;真正的“一键配图排版”要靠官方 PPT 助手或第三方平台&#xff08;博思 AiPPT、迅捷 AiPPT、Gamma、墨刀 AI 等&#xff09;。两条主流技术路…

Redis哈希(Hash):适合存储对象的数据结构,优势与坑点解析

Redis哈希&#xff08;Hash&#xff09;&#xff1a;适合存储对象的数据结构&#xff0c;优势与坑点解析 1. Redis哈希概述 1.1 什么是Redis哈希 Redis哈希&#xff08;Hash&#xff09;是一种映射类型&#xff08;Map&#xff09;&#xff0c;由多个字段值对&#xff08;fi…

Python的uv包管理工具使用

一、简介 uv是一个继Python版本管理、Python包管理、项目管理、虚拟环境管理于一体的工具&#xff0c;由于底层是用Rust编写的&#xff0c;uv的执行速度非常快。 安装 pip install uv镜像源设置 uv默认安装包是从pypi上下载的&#xff0c;速度比较慢。我们可以设置镜像源&#…

JavaScript事件机制与性能优化:防抖 / 节流 / 事件委托 / Passive Event Listeners 全解析

目标&#xff1a;把“为什么慢、卡顿从哪来、该怎么写”一次说清。本文先讲事件传播与主线程瓶颈&#xff0c;再给出四件法宝&#xff08;防抖、节流、事件委托、被动监听&#xff09;&#xff0c;最后用一套可复制的工具函数 清单收尾。1&#xff09;先理解“为什么会卡”&am…