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

如何将Python对象的指定属性导出为字典?

实现带标记@property属性导出为字典的其他方法

以下是几种替代你当前实现的方案,各有适用场景:

1. 元类预收集导出属性

通过元类在类定义阶段就把标记了@export_to_dict的属性名记录下来,避免每次调用to_dict时遍历所有属性,提升调用效率。

def export_to_dict(func):
    func._export_to_dict = True
    return func

class ExportMeta(type):
    def __new__(cls, name, bases, attrs):
        export_attrs = []
        for attr_name, attr_value in attrs.items():
            # 识别@property装饰的属性,检查其fget方法的标记
            if isinstance(attr_value, property) and hasattr(attr_value.fget, '_export_to_dict'):
                export_attrs.append(attr_name)
        attrs['_export_attrs'] = export_attrs
        return super().__new__(cls, name, bases, attrs)

class Foo(metaclass=ExportMeta):
    @export_to_dict
    @property
    def bar1(self):
        return 1

    @property
    def bar2(self):
        return {"smth": 2}

    @export_to_dict
    @property
    def bar3(self):
        return "a"

    @property
    def bar4(self):
        return [2, 3, 4]

    def to_dict(self):
        return {attr: getattr(self, attr) for attr in self._export_attrs}

2. 自定义Property子类

创建继承自property的专属子类,直接用它标记需要导出的属性,to_dict时通过类型筛选即可。

class ExportProperty(property):
    pass

class Foo:
    @ExportProperty  # 用自定义子类替代原生@property
    def bar1(self):
        return 1

    @property
    def bar2(self):
        return {"smth": 2}

    @ExportProperty
    def bar3(self):
        return "a"

    @property
    def bar4(self):
        return [2, 3, 4]

    def to_dict(self):
        result = {}
        # 遍历类属性,筛选ExportProperty类型
        for attr_name, attr_value in self.__class__.__dict__.items():
            if isinstance(attr_value, ExportProperty):
                result[attr_name] = getattr(self, attr_name)
        return result

3. 利用函数注解实现标记

不需要额外装饰器,直接给@property的方法添加自定义注解,to_dict时读取注解判断是否导出。

class Foo:
    @property
    def bar1(self):
        return 1
    # 给属性的fget方法添加导出标记
    bar1.fget.__annotations__['export'] = True

    @property
    def bar2(self):
        return {"smth": 2}

    @property
    def bar3(self):
        return "a"
    bar3.fget.__annotations__['export'] = True

    @property
    def bar4(self):
        return [2, 3, 4]

    def to_dict(self):
        result = {}
        for attr_name, attr_value in self.__class__.__dict__.items():
            if isinstance(attr_value, property):
                # 检查注解中的导出标记
                if attr_value.fget.__annotations__.get('export', False):
                    result[attr_name] = getattr(self, attr_name)
        return result

4. 类装饰器收集导出属性

和元类思路类似,但用类装饰器实现,无需修改元类,更轻量化。

def export_to_dict(func):
    func._export_to_dict = True
    return func

def collect_export_attrs(cls):
    export_attrs = []
    for attr_name, attr_value in cls.__dict__.items():
        if isinstance(attr_value, property) and hasattr(attr_value.fget, '_export_to_dict'):
            export_attrs.append(attr_name)
    cls._export_attrs = export_attrs
    return cls

@collect_export_attrs
class Foo:
    @export_to_dict
    @property
    def bar1(self):
        return 1

    @property
    def bar2(self):
        return {"smth": 2}

    @export_to_dict
    @property
    def bar3(self):
        return "a"

    @property
    def bar4(self):
        return [2, 3, 4]

    def to_dict(self):
        return {attr: getattr(self, attr) for attr in self._export_attrs}

各方案特点

  • 元类/类装饰器:适合多类复用导出逻辑的场景,提前收集属性,to_dict调用更高效
  • 自定义Property子类:语法简洁直观,可读性强
  • 函数注解:无需额外装饰器,利用Python原生特性,但标记方式稍显繁琐

内容的提问来源于stack exchange,提问作者StuffHappens

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:35:28