子类访问父类私有成员__MParamL报错,寻求技术解决方案
问题原因分析
你遇到的问题是Python的**名称修饰(Name Mangling)**机制导致的:Python中,以双下划线__开头的实例变量会被自动重命名为_父类名__变量名,目的是防止子类意外覆盖父类的私有变量。
在你的代码中,父类HashClass里的__MParamL会被Python重命名为_HashClass__MParamL,而子类UniversalHash中直接写self.__MParamL时,Python会尝试寻找_UniversalHash__MParamL,这显然不存在,所以抛出属性不存在的异常。
解决方案
方案1:使用父类提供的公共接口(推荐)
父类已经定义了GetParamL()方法来获取__MParamL的值,直接调用这个方法是最符合封装原则的做法:
# 子类中修改FindHash方法 def FindHash(self, Key): return (((self.__MParamK * Key) + self.__MParamC) % self.__MParamD) % self.GetParamL()
方案2:直接访问名称修饰后的变量(不推荐)
如果你一定要直接访问父类的私有变量,可以手动使用重命名后的变量名,但这种方式破坏了封装,不建议在生产代码中使用:
def FindHash(self, Key): return (((self.__MParamK * Key) + self.__MParamC) % self.__MParamD) % self._HashClass__MParamL
方案3:修改父类变量为受保护类型(折中方案)
如果希望子类可以直接访问该变量,同时提醒外部代码不要随意修改,可以把父类的变量改为单下划线_开头(Python中约定单下划线开头的变量为受保护变量):
# 修改父类HashClass class HashClass: def __init__(self): self._MParamL = int(0) # 单下划线代替双下划线 def SetParamL(self, Value): self._MParamL = Value def GetParamL(self): return self._MParamL def FindHash(self, Key): pass # 子类中直接访问_MParamL class UniversalHash(HashClass): # ...其他代码不变 def FindHash(self, Key): return (((self.__MParamK * Key) + self.__MParamC) % self.__MParamD) % self._MParamL
内容的提问来源于stack exchange,提问作者Alessio Vannucci
相关产品推荐
相关产品推荐

