如何处理两个非嵌套公共类私有属性的名称修饰问题
解决Python跨类访问私有属性的问题
错误原因分析
你的代码存在两个核心问题:
- 在
Second类的__init__方法中,__first.__size里的__first没有加self.前缀,Python会将其识别为全局变量,同时触发名称修饰规则,把__first解析为_Second__first,但First实例根本不存在这个属性,因此抛出AttributeError。 - 就算修正为
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
相关产品推荐
相关产品推荐

