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

如何在Python 2中实现带有序属性与字典接口的类?

Python 2 实现有序属性类的方案

实现思路

要满足需求,需结合元类记录类定义阶段的属性顺序,用OrderedDict维护实例新增属性的顺序,再通过特殊方法实现点访问与字典式访问的兼容,最后适配json.dumps的序列化逻辑。

完整代码实现

from collections import OrderedDict
import json

class OrderedAttrMeta(type):
    def __new__(cls, name, bases, attrs):
        # 收集类定义中的非方法属性,按定义顺序存储
        declared_attrs = []
        for attr_name, attr_value in attrs.items():
            if not callable(attr_value) and not attr_name.startswith('__'):
                declared_attrs.append(attr_name)
        # 将属性顺序绑定到类上
        attrs['_declared_attrs'] = declared_attrs
        return super(OrderedAttrMeta, cls).__new__(cls, name, bases, attrs)

class MyClass(object):
    __metaclass__ = OrderedAttrMeta
    someprop = 1
    otherprop = ""
    thirdprop = ""
    
    def __init__(self):
        # 用OrderedDict存储实例新增属性,保证顺序
        self._instance_attrs = OrderedDict()
    
    def say_hello(self):
        print("hello {}".format(self.someprop))
    
    # 支持字典式获取属性
    def __getitem__(self, key):
        if key in self._instance_attrs:
            return self._instance_attrs[key]
        return getattr(self, key)
    
    # 支持字典式设置属性
    def __setitem__(self, key, value):
        self._instance_attrs[key] = value
        # 同步设置为实例属性,支持点访问
        setattr(self, key, value)
    
    def keys(self):
        # 合并类定义属性与实例新增属性,排除方法
        result = self._declared_attrs[:]
        result.extend(self._instance_attrs.keys())
        return result
    
    # 让json.dumps能正确遍历键
    def __iter__(self):
        for key in self.keys():
            yield key
    
    # 序列化时返回有序字典,保证输出顺序
    def __getstate__(self):
        ordered_dict = OrderedDict()
        for key in self.keys():
            ordered_dict[key] = getattr(self, key)
        return ordered_dict

# 测试代码
if __name__ == "__main__":
    myobj = MyClass()
    myobj.newprop = "test"
    # 测试点访问与字典访问
    print(myobj.newprop)  # 输出: test
    print(myobj["newprop"])  # 输出: test
    
    # 测试keys()顺序
    print(myobj.keys())  # 输出: ['someprop', 'otherprop', 'thirdprop', 'newprop']
    
    # 测试json序列化
    json_str = json.dumps(myobj)
    print(json_str)  # 输出: {"someprop": 1, "otherprop": "", "thirdprop": "", "newprop": "test"}

关键细节说明

  • 元类OrderedAttrMeta:在类创建阶段遍历属性,筛选出非方法、非内置双下划线开头的属性,按定义顺序存入_declared_attrs,确保类属性的顺序。
  • 实例属性维护:用_instance_attrs这个OrderedDict保存实例新增属性,保证新增属性的顺序。
  • 双访问兼容:通过__getitem__和__setitem__实现字典式访问,设置属性时同步调用setattr,保证点访问可用。
  • json序列化适配:实现__iter__让json模块能遍历键,__getstate__返回有序字典,确保序列化后的json字符串顺序符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 09:27:23