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

如何在动态父类名场景下从子类实例获取父类名称改写属性

如何动态访问父类的名称改写属性?

Python中,双下划线开头的私有属性会被名称改写机制处理,变成_类名__属性名的形式,以此实现封装。如果要动态访问父类的这类属性,而不硬编码父类名称,可以按以下方式实现:

方案1:针对单一直接父类

通过子类的__bases__属性获取直接父类,再构造改写后的属性名:

class Foo:
    def __init__(self):
        self.__is_init = False

    async def init(self):
        self.__is_init = True

class Bar(Foo):
    pass

bar = Bar()

# 获取子类的直接父类
parent_cls = bar.__class__.__bases__[0]
# 构造名称改写后的属性名
target_attr = f"_{parent_cls.__name__}__is_init"
# 获取属性值
is_init = getattr(bar, target_attr)
print(is_init)  # 输出: False

方案2:支持多重继承场景

如果子类继承了多个父类,可以遍历所有父类,检查并获取目标属性:

def get_parent_private_attr(instance, raw_attr_name):
    """从实例的父类中获取指定的私有属性"""
    for base_cls in instance.__class__.__bases__:
        modified_attr = f"_{base_cls.__name__}__{raw_attr_name}"
        if hasattr(instance, modified_attr):
            return getattr(instance, modified_attr)
    raise AttributeError(f"未找到包含私有属性__{raw_attr_name}的父类")

# 使用示例
bar = Bar()
print(get_parent_private_attr(bar, "is_init"))  # 输出: False

更优雅的替代方案

Python设计名称改写的初衷是为了封装,直接访问私有属性违背设计原则。更合理的方式是让父类提供公开的访问接口:

class Foo:
    def __init__(self):
        self.__is_init = False

    async def init(self):
        self.__is_init = True

    # 提供公开方法获取私有属性值
    def is_initialized(self):
        return self.__is_init

class Bar(Foo):
    pass

bar = Bar()
print(bar.is_initialized())  # 输出: False

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:05:21