Python函数双下划线参数问题及CPython名字修饰实现查询
问题1解答
名字修饰(name mangling)仅在类定义范围内生效,普通函数(包括内置函数)的参数或变量使用双下划线开头不会触发修饰(你的测试代码也验证了这一点:wat1里的__a、wat2里的__b在字节码中仍保留原名称)。
__arg1、__arg2用双下划线命名,是为了标记它们是内部参数,禁止用户通过关键字参数显式指定——max的设计意图是让用户通过位置参数传递待比较的值,而key是对外暴露的可选配置参数,需要用户能通过关键字参数明确指定,因此使用常规命名。
问题2解答
在非类的函数场景中,双下划线开头的参数不会触发name mangling,它是一种命名约定,作用包括:
- 明确标记参数属于内部实现细节,不属于公开API,提示用户不要通过关键字参数传递该参数(比如不要写
max(__arg1=1, __arg2=2)); - 避免参数名冲突:后续若给
max新增公开参数,不会和这些内部参数名产生冲突; - 对内置函数的类型注解而言,这种命名能清晰区分“用户应传入的参数”和“内部逻辑的参数占位”。
问题3解答
name mangling是在编译阶段处理的,核心逻辑位于CPython源码的Python/compile.c文件中。当编译器处理类定义内部的标识符时,若遇到以双下划线开头且不以双下划线结尾的名字,会将其重写为_ClassName__xxx的形式(ClassName为当前类的名称)。
具体来说,相关处理逻辑在compiler_name函数或处理类成员的代码分支中,负责识别符合条件的标识符并完成重命名。
补充测试代码:
def wat1(__a): def wat2(__b): return __b, __a return __a print(wat1.__code__.co_varnames) print(wat1.__code__.co_cellvars) dis.dis(wat1)
输出(Linux环境Python==3.10.8):
('__a', 'wat2') ('__a',) 21 0 LOAD_FAST 0 (__a) 2 RETURN_VALUE 22 0 LOAD_FAST 0 (__b) 2 LOAD_DEREF 0 (__a) 4 BUILD_TUPLE 2 6 RETURN_VALUE
内容的提问来源于stack exchange,提问作者hoshino
相关产品推荐
相关产品推荐

