wja*_*rea 5 python identifier name-mangling magic-methods
我正在编写一个项目,提供有关变量名称的建议,并且我希望它能够判断名称是否与任何保留的标识符类匹配。第一个(“private”)非常简单,只是name.startswith('_'),但 dunder 和类私有名称更复杂。有没有内置函数可以告诉我?如果不是,Python 使用的内部规则是什么?
对于 dunder,检查name.startswith('__') and name.endswith('__')不起作用,因为它会匹配'__'。也许像这样的正则表达式^__\w+__$会起作用?
对于类私有,name.startswith('__')不起作用,因为 dunder 名称不会被破坏,也不会像 那样只包含下划线的名称'___'。所以看来我必须检查名称是否以两个下划线开头,不以两个下划线结尾,并且至少包含一个非下划线字符。是对的吗?在代码中:
name.startswith('__') and not name.endswith('__') and any(c != '_' for c in name)
Run Code Online (Sandbox Code Playgroud)
我最关心的是边缘情况,所以我想确保我的规则 100% 正确。我读过对象名称之前的单下划线和双下划线的含义是什么?但细节还不够。
wja*_*rea 10
基于(从Python 3.7开始使用is_dunder_name)Objects/typeobject.cstr.isascii:
len(name) > 4 and name.isascii() and name.startswith('__') and name.endswith('__')
Run Code Online (Sandbox Code Playgroud)
或者,该正则表达式^__\w+__$也可以工作,但需要re.ASCII启用它以确保\w仅匹配 ASCII 字符。
这些规则记录在标识符(名称)下:
name.startswith('__') and not name.endswith('__')
Run Code Online (Sandbox Code Playgroud)
(旁注:not name.endswith('__')确保名称至少包含一个非下划线。)
_Py_MangleinPython/compile.c也有一个 C 实现,但它包括对点的检查,严格来说,带有点的名称是“属性引用”,而不是名称。那相当于:
name.startswith('__') and not name.endswith('__') and not '.' in name
Run Code Online (Sandbox Code Playgroud)
PS 我几乎看不懂 C,所以对这些翻译持保留态度。