You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类内使用双下划线装饰器触发Name mangling的解决方案咨询

在类中使用模块级双下划线开头的装饰器

这个问题的根源在于Python的**名称改写(name mangling)**机制:当你在类内部使用双下划线__开头的标识符时,Python会自动将其重命名为_类名__标识符的格式,目的是避免子类意外覆盖父类的私有属性/方法。所以当你在类A里写@__decorator时,Python实际会去查找_A__decorator,但你的装饰器是定义在模块层面的__decorator,自然就会抛出NameError。

要在保留双下划线命名规范的前提下解决这个问题,有几种可行的方法:

方法1:通过globals()直接引用模块级命名空间

globals()函数会返回当前模块的全局命名空间字典,我们可以直接从中取出模块级的__decorator,这样就能避开类内部的名称改写:

# 模块级的双下划线装饰器
def __decorator(fn):
    return fn

class A(object):
    # 直接从全局命名空间获取装饰器
    @globals()['__decorator']
    def test(self):
        return 1

print(A().test())  # 输出:1

方法2:借助模块自身引用

如果你的脚本是主模块(即__name__ == '__main__'),也可以通过__import__获取模块自身,再引用装饰器:

def __decorator(fn):
    return fn

class A(object):
    @__import__('__main__').__decorator
    def test(self):
        return 1

print(A().test())  # 输出:1

这种方法不如globals()简洁,但在一些特殊场景下也能生效。

方法3:提前绑定到非双下划线变量(折中方案)

如果你觉得上面的写法不够直观,也可以在类定义前把双下划线装饰器赋值给一个普通变量,然后在类里使用这个变量——虽然这会多一个别名,但能保持装饰器本身的双下划线命名:

def __decorator(fn):
    return fn

# 绑定到普通变量
_decorator_alias = __decorator

class A(object):
    @_decorator_alias
    def test(self):
        return 1

print(A().test())  # 输出:1

以上几种方法都能让你在类内部正确引用模块级的双下划线装饰器,根据自己的代码场景选择合适的即可。

内容的提问来源于stack exchange,提问作者jabozzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:05:17