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

如何处理两个非嵌套公共类私有属性的名称修饰问题

解决Python跨类访问私有属性的问题

错误原因分析

你的代码存在两个核心问题:

  1. 在Second类的__init__方法中,__first.__size里的__first没有加self.前缀,Python会将其识别为全局变量,同时触发名称修饰规则,把__first解析为_Second__first,但First实例根本不存在这个属性,因此抛出AttributeError。
  2. 就算修正为self.__first.__size,依然会报错——因为First类的__size经过名称修饰后,实际存储的属性名是_First__size,而非表面的__size。

正确解决方法

方法1:直接使用名称修饰后的属性名(不推荐)

既然明确Python的名称修饰规则,可直接通过_类名__属性名的格式访问:

class First:
    def __init__(self) -> None:
        self.__size = 5  # 赋值具体值用于测试

    def __len__(self) -> int:
        return self.__size


class Second:
    def __init__(self, first: First) -> None:
        self.__first = first
        # 直接访问First类修饰后的私有属性
        self.__size = self.__first._First__size

    def __len__(self) -> int:
        return self.__size

# 测试
f = First()
s = Second(f)
print(len(s))  # 输出5

⚠️ 注意:这种方法破坏了类的封装性,违背私有属性的设计初衷,仅作原理演示,实际开发不建议使用。

方法2:通过公开接口访问(推荐)

在First类中提供公开方法来暴露私有属性,比如利用已有的__len__方法,或者新增专门的获取方法:

class First:
    def __init__(self) -> None:
        self.__size = 5

    def __len__(self) -> int:
        return self.__size
    
    # 可选:新增专门的属性获取方法
    def get_size(self) -> int:
        return self.__size


class Second:
    def __init__(self, first: First) -> None:
        self.__first = first
        # 利用First类的__len__方法获取size
        self.__size = len(self.__first)
        # 或者使用get_size方法:self.__size = self.__first.get_size()

    def __len__(self) -> int:
        return self.__size

# 测试
f = First()
s = Second(f)
print(len(s))  # 输出5

这种方式完全符合Python的封装原则,是最规范的解决方案。

方法3:改为受保护属性(单下划线)

如果First类的属性不需要严格私有,可将__size改为_size(单下划线)——这是Python约定俗成的“受保护”属性,不会触发名称修饰,外部类可直接访问,同时提示开发者不要随意修改:

class First:
    def __init__(self) -> None:
        self._size = 5  # 单下划线标识的受保护属性

    def __len__(self) -> int:
        return self._size


class Second:
    def __init__(self, first: First) -> None:
        self.__first = first
        self.__size = self.__first._size

    def __len__(self) -> int:
        return self.__size

# 测试
f = First()
s = Second(f)
print(len(s))  # 输出5

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 00:57:42