如何按编写顺序获取类中方法并实现自动按序执行?
解决方案:按定义顺序自动执行类方法并支持范围执行
以下是两种可行的实现方案,均能满足保留方法定义顺序、自动执行和指定范围执行的需求:
方案一:装饰器标记步骤(推荐,更灵活)
通过装饰器显式标记需要按顺序执行的步骤方法,同时使用元类确保每个子类拥有独立的步骤列表,避免跨子类干扰。
代码实现
class CommandSequenceMeta(type): def __new__(cls, name, bases, attrs): # 为每个子类初始化独立的步骤列表 new_class = super().__new__(cls, name, bases, attrs) new_class._steps = [] return new_class class CommandSequence(metaclass=CommandSequenceMeta): @classmethod def step(cls, func): """标记方法为需要按顺序执行的步骤""" cls._steps.append(func) return func def run_all(self): """按定义顺序执行所有标记的步骤""" for func in self._steps: func(self) def run_from_to(self, start_method_name, end_method_name): """执行从指定起始方法到结束方法的子序列""" step_names = [func.__name__ for func in self._steps] try: start_idx = step_names.index(start_method_name) end_idx = step_names.index(end_method_name) + 1 # 包含结束方法 for func in self._steps[start_idx:end_idx]: func(self) except ValueError as e: raise ValueError(f"步骤方法未找到:{e}") # 示例子类 class QueryBundle(CommandSequence): @CommandSequence.step def print_something_else(self): """ 步骤1:打印内容1 工具可识别的文档字符串 """ print("something else") @CommandSequence.step def print_some_other_thing(self): """步骤2:打印内容2""" print("something other thing") @CommandSequence.step def print_something(self): """步骤3:打印内容3""" print("something") # 非步骤方法(不会被自动执行) def helper_method(self): print("这是辅助方法,不会自动运行") # 使用示例 test = QueryBundle() test.run_all() print("\n---执行指定范围---") test.run_from_to('print_something_else', 'print_some_other_thing')
执行结果
something else something other thing something ---执行指定范围--- something else something other thing
方案二:自动收集类方法(无需装饰器)
利用Python 3.7+中类__dict__保留插入顺序的特性,自动收集所有非特殊方法(排除run_all/run_from_to)作为步骤。
代码实现
class CommandSequence: def __init__(self): # 从类的__dict__中按顺序收集步骤方法 self._steps = [] for attr_name, attr_value in self.__class__.__dict__.items(): if (callable(attr_value) and not attr_name.startswith('__') and attr_name not in ('run_all', 'run_from_to')): self._steps.append(attr_value) def run_all(self): for func in self._steps: func(self) def run_from_to(self, start_method_name, end_method_name): step_names = [func.__name__ for func in self._steps] try: start_idx = step_names.index(start_method_name) end_idx = step_names.index(end_method_name) + 1 for func in self._steps[start_idx:end_idx]: func(self) except ValueError as e: raise ValueError(f"步骤方法未找到:{e}") # 示例子类 class QueryBundle(CommandSequence): def print_something_else(self): """步骤1:打印内容1""" print("something else") def print_some_other_thing(self): """步骤2:打印内容2""" print("something other thing") def print_something(self): """步骤3:打印内容3""" print("something") # 使用示例 test = QueryBundle() test.run_all()
说明
- 此方案无需额外装饰器,但所有符合条件的类方法都会被视为步骤,无法区分步骤方法和辅助方法。
- 仅适用于Python 3.7及以上版本(因为低版本Python的类
__dict__不保证顺序)。
内容的提问来源于stack exchange,提问作者Error_2646
相关产品推荐
相关产品推荐

