能否以参数指定的类为父类实现继承?技术实现咨询
实现动态方法调用/类继承,直接使用图形类的静态方法
当然可行!你想要的效果本质是让Figure实例能直接调用目标图形类(比如Cube)的静态方法,不用再通过中间的element属性转发。下面给你两种更安全、更符合Python风格的实现方案,同时替换掉原有代码里不安全的exec和eval:
方法一:用__getattr__实现方法代理
这种方式改动最小,借助Python的属性查找魔法方法,把未定义的方法调用自动转发给self.element:
import importlib from OpenGL.GL import * class Figure: def __init__(self, figure_type): # 安全导入模块和类,替代风险较高的exec/eval module = importlib.import_module(f'figures.{figure_type.lower()}') self.element = getattr(module, figure_type)() def __getattr__(self, name): # 当实例找不到对应属性/方法时,自动去element中查找 return getattr(self.element, name) def create(self, vertices): glBegin(GL_LINES) for edge in self.get_edges(): # 现在可以直接调用self.get_edges()了! for vertex in edge: glColor3fv((0.5, 0, 0)) glVertex3fv(vertices[vertex]) glEnd() # 你的图形类保持原有实现即可 class Cube: @staticmethod def get_edges(): return ((0, 1),(0, 3),(0, 4),(2, 1),(2, 3),(2, 7),(6, 3),(6, 4),(6, 7),(5, 1),(5, 4),(5, 7))
用法示例
fig = Figure('Cube') print(fig.get_edges()) # 直接调用,效果和self.element.get_edges()完全一致 fig.create(your_vertex_data) # 正常执行绘制逻辑
这种方案的优势是对原有代码改动极小,完全兼容你原来的调用逻辑,非常适合快速改造。
方法二:动态创建继承自目标图形类的子类
如果你希望从语义上真正实现“继承”(让Figure实例拥有目标类的方法所有权),可以动态生成一个同时继承基础逻辑和目标图形类的子类:
import importlib from OpenGL.GL import * # 提取通用的绘制逻辑作为基础类 class FigureBase: def create(self, vertices): glBegin(GL_LINES) for edge in self.get_edges(): for vertex in edge: glColor3fv((0.5, 0, 0)) glVertex3fv(vertices[vertex]) glEnd() def create_figure(figure_type): # 安全导入目标图形类 module = importlib.import_module(f'figures.{figure_type.lower()}') figure_class = getattr(module, figure_type) # 动态创建子类:同时继承FigureBase和目标图形类 DynamicFigure = type( f'DynamicFigure_{figure_type}', # 子类名称(可自定义) (FigureBase, figure_class), # 继承的父类列表 {} # 额外类属性(可选) ) return DynamicFigure() # Cube类保持原有实现 class Cube: @staticmethod def get_edges(): return ((0, 1),(0, 3),(0, 4),(2, 1),(2, 3),(2, 7),(6, 3),(6, 4),(6, 7),(5, 1),(5, 4),(5, 7))
用法示例
fig = create_figure('Cube') isinstance(fig, Cube) # 返回True,说明实例确实继承了Cube类 fig.get_edges() # 直接调用父类的静态方法 fig.create(your_vertex_data)
这种方案更符合面向对象的继承逻辑,实例会真正拥有目标类的所有方法和属性,适合需要依赖继承关系的场景。
为什么要替换exec和eval?
原来的exec和eval存在代码注入风险——如果figure_type参数来自用户输入,恶意输入可能会执行任意危险代码。用importlib.import_module和getattr是Python官方推荐的安全导入方式,能完全避免这个问题。
内容的提问来源于stack exchange,提问作者Ethr
相关产品推荐
相关产品推荐

