如何在Python类方法中访问实例添加的双下划线属性?
Python中Rectangle类area方法访问__breadth属性的问题及解决办法
核心问题解答
不能直接访问。你遇到的问题是Python的**名称修饰(Name Mangling)**机制导致的:
- 类内部定义的
__length、__breadth这类双下划线开头的属性,Python会自动将其重命名为_类名__属性名(比如__length会变成_Rectangle__length),目的是避免子类意外覆盖父类的私有属性。 - 你在实例外部给
b添加的b.__breadth,实际上存储在实例的__dict__中就是__breadth,和类内部area方法要访问的_Rectangle__breadth是完全不同的两个属性,所以调用area()时会找不到目标属性而报错。
可行解决办法
方法1:遵循封装原则,通过类内部方法设置属性
这是最规范的做法,通过类提供的接口来管理私有属性:
class Rectangle: def __init__(self, L): self.__length = L self.__breadth = None # 初始化时先设为None def set_breadth(self, breadth): self.__breadth = breadth def area(self): if self.__breadth is None: raise ValueError("请先设置breadth属性") return self.__length * self.__breadth # 使用示例 b = Rectangle(10) b.set_breadth(5) print(b.area()) # 输出50
方法2:直接访问名称修饰后的属性(不推荐)
如果你非要在外部修改类内部的私有属性,可以直接使用Python重命名后的属性名,但这种做法破坏了类的封装性,不建议在实际开发中使用:
class Rectangle: def __init__(self, L): self.__length = L def area(self): return self.__length * self.__breadth # 使用示例 b = Rectangle(10) b._Rectangle__breadth = 5 # 使用重命名后的属性名 print(b.area()) # 输出50
方法3:改用单下划线约定私有属性
如果不需要强制的私有属性保护,可以用单下划线开头的属性(这是Python社区约定的“私有”属性,外部可以访问但不建议随意修改):
class Rectangle: def __init__(self, L): self._length = L def area(self): return self._length * self._breadth # 使用示例 b = Rectangle(10) b._breadth = 5 print(b.area()) # 输出50
内容的提问来源于stack exchange,提问作者Dr. Jahiruddin
相关产品推荐
相关产品推荐

