Python访问私有内部类__OnlyOne报AttributeError错误如何解决
错误原因
这个报错是Python双下划线私有属性的**名称改写(Name Mangling)**机制导致的:
- 双下划线开头的类属性,Python会自动将其重命名为
_类名__属性名格式,避免不同类的同名属性冲突 - 你的
__parking_floors是定义在内部类__OnlyOne中的,所以实际存储的属性名为_ParkingLot__OnlyOne__parking_floors - 当你在外部类
ParkingLot的方法中写__parking_floors时,Python会自动将其改写为_ParkingLot__parking_floors,两个名称不匹配,因此触发属性不存在的错误
解决方案
推荐3种可行方案,按优先级从高到低排序:
方案1:使用公有方法封装内部类操作(最符合封装规范)
给内部类新增操作属性的公有方法,外部类直接调用方法即可,不需要直接访问私有属性:
class ParkingLot: instance = None class __OnlyOne: def __init__(self, name, address): self.__name = name self.__address = address self.__parking_floors = [] # 新增公有方法操作私有属性 def add_parking_floor(self, floor): self.__parking_floors.append(floor) def __init__(self, name, address): if not ParkingLot.instance: ParkingLot.instance = ParkingLot.__OnlyOne(name, address) else: ParkingLot.instance.__name = name ParkingLot.instance.__address = address def __getattr__(self, name): return getattr(self.instance, name) def add_parking_floor(self, floor): # 直接调用内部类的公有方法 ParkingLot.instance.add_parking_floor(floor) PL = ParkingLot('Test Parking Lot', 'Bombay') PL.add_parking_floor('First Floor')
方案2:将私有属性改为单下划线开头的保护属性
单下划线开头的属性是Python约定的类内部使用属性,不会触发名称改写机制,外部可以直接访问,只需要修改两处代码:
- 内部类
__OnlyOne的__init__中将self.__parking_floors = []改为self._parking_floors = [] - 外部类
add_parking_floor方法中改为ParkingLot.instance._parking_floors.append(floor)
方案3:直接使用改写后的完整属性名访问(不推荐)
直接硬编码写改写后的属性名可临时解决问题,但可读性差,不建议长期使用:
def add_parking_floor(self, floor): ParkingLot.instance._ParkingLot__OnlyOne__parking_floors.append(floor)
内容的提问来源于stack exchange,提问作者myquest
相关产品推荐
相关产品推荐

