You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何简化带排序选项的重复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:55:14