Python 参数填充四大定律:
- 1. 位置先行,顺序填充:位置参数按序号填入区段 1 和 3,余者入
*args 或报错。 - 2. 关键字后发,查漏补缺:关键字参数匹配区段 3 和 5 的空位,余者入
**kwargs 或报错。 - 3. 禁区拦截,严禁越权:关键字参数严禁触碰区段 1,触碰即报错。
- 4. 一坑一人,禁止重填:关键字参数严禁映射已被位置参数占用的区段 3 槽位。
具体来说:
位置参数先填 1 和 3 区域,填不满由关键字参数补充。如果满了,关键字参数就不能再填充了。
关键字参数如果匹配到 1,直接报错。匹配到 3 非空白位置也要报错。只能匹配 3 当中空白位置和 5 区域。
多余的位置参数和关键字参数可以进入溢出容器:*args, **kwargs。
一、 函数定义端的原则(制定协议)
在定义端,通过 / 、*、 *args 、**kwargs、将参数空间划分为三个核心权限区和两个溢出捕获区:
- 1. 拓扑顺序:必须严格遵守上述 1-7 的区段顺序。例如,你不能在
*args 之后定义标准参数,也不能在 / 之前定义带 * 的参数。 - 2. 默认值后置原则:在同一个“权限区段”(如区段 3)内,带默认值的参数必须排在无默认值参数的后面。
- •
/** (位置闸门)**:确保其左侧(区段 1)的标识符对调用者不可见,只能通过位置填充。 - •
*** (关键字闸门)**:确保其右侧(区段 5)的槽位不会被位置流误填,强制调用者指名道姓。
- •
*args(区段 6)负责收集位置参数的残余。 - •
**kwargs(区段 7)负责收集关键字参数的残余。它必须是整个定义的最后一个参数。
二、 函数调用端的原则(执行填充)
在调用端,你的核心任务是合规填充。
- 1. 位置实参优先原则:位置实参必须在关键字实参之前。一旦在代码中写下了第一个
key=value,后面绝对不允许再出现纯粹的值。 - 2. 不可重复填充原则:每一个形参槽位有且只能被填充一次。
- • 如果位置流已经填了某个槽位,关键字流再次映射该名时会报错。
- • 如果关键字流重复指定同一个名字,会报语法错误。
- • 位置参数填充范围:从区段 1 开始,止于区段 3。它绝对无法穿过
* 闸门进入区段 5。 - • 关键字参数填充范围:从区段 3 开始,止于区段 5。它绝对无法越过
/ 闸门进入区段 1。
- • 使用
*iterable 解包时,它被视为位置流,遵循位置流的射程和顺序。 - • 使用
**mapping 解包时,它被视为关键字流,遵循关键字流的映射规则。
三、 参数填充流程
当函数被调用时,程序先处理位置参数,再处理关键字参数,最后处理默认值和缺失检查。
位置参数的作为区间 :1 -> 3 -> 6(按从左到右的顺序),无法进入 5(仅限关键字区)
关键字参数的作用区间:(3 U 5) -> 7(3、5 不强调顺序),无法进入 1(仅限位置区)
1、处理位置参数
位置参数从左至右填充区段 1、3,无法进入区段 5:
- • 位置参数耗尽,但区段 1 或区段 3 仍有空槽位。关键字参数可以补充 3,无法补充 1。
- 2. 位置参数满了或溢出:不再需要关键字参数补充。如果溢出,要么进入*args 元组,要么报错。
- 1. 位置参数填满了区段 1 和区段 3,关键字参数就无法映射这部分位置了,只能尝试映射区段 5 或进入区段 7。
- 2. 如果溢出了:存在区段 6 (
*args),剩余数据存入元组;若不存在,抛出异常。
2、处理关键字参数
关键字参数按名称匹配区段 3、5,无法进入区段 1:
- • 理由:这是语法层面的强制隔离,防止调用者依赖那些可能被开发者随时修改名字的位置参数。
- • 未命中任何区段(1、3、5 区段都无此形参):
- • 存在区段 7 (
****kwargs**):将该键值对存入字典。 - • 不存在区段 7:报错
TypeError: got an unexpected keyword argument 'x'。
3、填充默认值与缺失检查
- • 默认值注入:检查所有未被绑定的槽位。若有默认值则填入。否则抛出异常。
四、总结
- • 定义端:通过
/ 、*、 *args 、**kwargs、将参数空间划分为三个核心权限区和两个溢出捕获区。 - • 调用端:位置在前,关键字在后,不能重复,不能越权。