如何简化带排序选项的重复Revit API元素获取函数?
复用Revit元素提取函数的排序逻辑
我写了一堆重复的Revit元素提取函数,每个都带可选的sort_by_name布尔参数,用来在返回元素列表前按名称排序。想问问能不能用父函数把排序逻辑复用起来?
原代码示例
def get_electrical_equipment(sort_by_name = False): elements = DB.FilteredElementCollector(revit.doc)\ .OfCategory(DB.BuiltInCategory.OST_ElectricalEquipment)\ .WhereElementIsNotElementType()\ .ToElements() if sort_by_name: elements.sort(key=lambda x: x.Name) return elements def get_panel_schedules(sort_by_name = False): elements = DB.FilteredElementCollector(revit.doc)\ .WherePasses(DB.ElementClassFilter(DB.Electrical.PanelScheduleView))\ .WhereElementIsNotElementType()\ .ToElements() if sort_by_name: elements.sort(key=lambda x: x.Name) return elements def get_panel_schedule_sheet_instances(sort_by_name = False): elements = DB.FilteredElementCollector(revit.doc)\ .OfClass(DB.Electrical.PanelScheduleSheetInstance)\ .ToElements() if sort_by_name: elements.sort(key=lambda x: x.Name) return elements
两种可行的复用方案
方案1:装饰器封装排序逻辑
写一个装饰器专门处理排序,让每个提取函数只负责获取元素,不用重复写排序代码:
def sort_by_name_decorator(func): def wrapper(sort_by_name=False): elements = func() if sort_by_name: elements.sort(key=lambda x: x.Name) return elements return wrapper # 改造原函数,移除排序相关代码 @sort_by_name_decorator def get_electrical_equipment(): return DB.FilteredElementCollector(revit.doc)\ .OfCategory(DB.BuiltInCategory.OST_ElectricalEquipment)\ .WhereElementIsNotElementType()\ .ToElements() @sort_by_name_decorator def get_panel_schedules(): return DB.FilteredElementCollector(revit.doc)\ .WherePasses(DB.ElementClassFilter(DB.Electrical.PanelScheduleView))\ .WhereElementIsNotElementType()\ .ToElements() @sort_by_name_decorator def get_panel_schedule_sheet_instances(): return DB.FilteredElementCollector(revit.doc)\ .OfClass(DB.Electrical.PanelScheduleSheetInstance)\ .ToElements()
调用方式和原来完全一致:get_electrical_equipment(sort_by_name=True)。
方案2:通用元素获取函数
把元素过滤逻辑作为参数传入通用函数,进一步复用代码结构,适合后续扩展更多元素类型:
def get_elements(filter_func, sort_by_name=False): elements = filter_func(revit.doc) if sort_by_name: elements.sort(key=lambda x: x.Name) return elements # 定义各元素类型的过滤逻辑 def filter_electrical_equipment(doc): return DB.FilteredElementCollector(doc)\ .OfCategory(DB.BuiltInCategory.OST_ElectricalEquipment)\ .WhereElementIsNotElementType()\ .ToElements() def filter_panel_schedules(doc): return DB.FilteredElementCollector(doc)\ .WherePasses(DB.ElementClassFilter(DB.Electrical.PanelScheduleView))\ .WhereElementIsNotElementType()\ .ToElements() def filter_panel_schedule_sheet_instances(doc): return DB.FilteredElementCollector(doc)\ .OfClass(DB.Electrical.PanelScheduleSheetInstance)\ .ToElements() # 调用示例 electrical_equip = get_elements(filter_electrical_equipment, sort_by_name=True) panel_schedules = get_elements(filter_panel_schedules, sort_by_name=False)
内容的提问来源于stack exchange,提问作者mybluesock
相关产品推荐
相关产品推荐

