如何根据数据加载条件隐藏类中不匹配的绘图方法?
解决方案
下面给你三种可行的实现方式,你可以根据自己的需求选择:
方法1:动态删除实例上的无关方法
在识别出数据类型后,直接删除实例中不需要的绘图方法。这样查看实例属性时,无关方法会被隐藏,调用也会直接报错。
修改后的代码:
class data_reader(): def __init__(self): self.load_data() self.data_type() self.common_method_1() self.common_method_2() def load_data(self): # 这里模拟加载数据,实际根据真实数据判断类型 self.data_structure_type = 1 # 赋值为1/2/3对应三种数据结构 def data_type(self): # 按数据类型删除不需要的绘图方法 method_map = { 1: {'plot_data_2', 'plot_data_3'}, 2: {'plot_data_1', 'plot_data_3'}, 3: {'plot_data_1', 'plot_data_2'} } for method_name in method_map[self.data_structure_type]: if hasattr(self, method_name): delattr(self, method_name) def common_method_1(self): print("通用方法1") def common_method_2(self): print("通用方法2") def plot_data_1(self): print("绘制数据结构1的图表") def plot_data_2(self): print("绘制数据结构2的图表") def plot_data_3(self): print("绘制数据结构3的图表") if __name__ == "__main__": a = data_reader() print(dir(a)) # 输出里看不到plot_data_2和plot_data_3 a.plot_data_1() # 正常执行 # a.plot_data_2() # 会抛出AttributeError
特点:实现简单粗暴,见效快;但属于动态修改实例属性,后续如果要恢复方法需要重新绑定,灵活性稍差。
方法2:用工厂函数返回对应子类
把通用方法放到基类,每种数据结构对应一个子类,只实现自己的绘图方法。用工厂函数加载数据、判断类型,返回对应的子类实例。这样实例天生只带对应的数据结构的绘图方法。
代码示例:
# 基类:存放所有数据结构通用的方法 class BaseDataReader: def __init__(self): self.common_method_1() self.common_method_2() def common_method_1(self): print("通用方法1") def common_method_2(self): print("通用方法2") # 子类1:对应数据结构1 class DataReaderType1(BaseDataReader): def plot_data_1(self): print("绘制数据结构1的图表") # 子类2:对应数据结构2 class DataReaderType2(BaseDataReader): def plot_data_2(self): print("绘制数据结构2的图表") # 子类3:对应数据结构3 class DataReaderType3(BaseDataReader): def plot_data_3(self): print("绘制数据结构3的图表") # 工厂函数:负责加载数据并返回对应实例 def create_data_reader(): # 加载数据并判断类型,这里模拟是类型1 data_structure_type = 1 if data_structure_type == 1: return DataReaderType1() elif data_structure_type == 2: return DataReaderType2() elif data_structure_type == 3: return DataReaderType3() if __name__ == "__main__": a = create_data_reader() print(dir(a)) # 只有plot_data_1 a.plot_data_1()
特点:完全符合面向对象设计原则,结构清晰,后续加新数据结构只需要加子类,维护起来更方便;但需要拆分类,前期代码量稍多。
方法3:通过__dir__和__getattr__控制可见性
不删除实例方法,而是通过__dir__过滤掉无关方法(让用户看不到),用__getattr__拦截对无关方法的调用并抛出明确错误。
代码示例:
class data_reader(): def __init__(self): self.load_data() self.data_type() self.common_method_1() self.common_method_2() def load_data(self): # 模拟加载类型1的数据 self.data_structure_type = 1 def data_type(self): # 这里可以写数据类型判断的逻辑 pass def common_method_1(self): print("通用方法1") def common_method_2(self): print("通用方法2") def plot_data_1(self): print("绘制数据结构1的图表") def plot_data_2(self): print("绘制数据结构2的图表") def plot_data_3(self): print("绘制数据结构3的图表") def __dir__(self): # 过滤掉当前数据结构不支持的绘图方法 original_attrs = super().__dir__() exclude = [] if self.data_structure_type == 1: exclude = ['plot_data_2', 'plot_data_3'] elif self.data_structure_type == 2: exclude = ['plot_data_1', 'plot_data_3'] elif self.data_structure_type == 3: exclude = ['plot_data_1', 'plot_data_2'] return [attr for attr in original_attrs if attr not in exclude] def __getattr__(self, name): # 拦截对无关方法的调用,抛出明确错误 invalid_methods = { 1: {'plot_data_2', 'plot_data_3'}, 2: {'plot_data_1', 'plot_data_3'}, 3: {'plot_data_1', 'plot_data_2'} } if name in invalid_methods.get(self.data_structure_type, set()): raise AttributeError(f"当前数据结构类型{self.data_structure_type}不支持方法{name}") # 其他不存在的属性按默认逻辑处理 raise AttributeError(f"'data_reader' object has no attribute '{name}'") if __name__ == "__main__": a = data_reader() print(dir(a)) # 看不到plot_data_2和plot_data_3 a.plot_data_1() # a.plot_data_2() # 抛出AttributeError,提示不支持该方法
特点:不修改实例的方法绑定,只是控制可见性和访问权限,灵活性高;但代码量稍大,需要维护过滤规则。
内容的提问来源于stack exchange,提问作者Woodywoodleg
相关产品推荐
相关产品推荐

