Python 2.7.13中JSON反序列化到__dict__的跨机器异常问题咨询
问题分析与解决
差异原因
出现这种跨机器差异主要有两种可能:
- 经典类与新式类的区别:Python 2.7中存在经典类(默认不继承
object)和新式类(显式继承object)的差异。经典类的__dict__是类级别的属性,直接给实例的self.__dict__赋值不会替换实例的属性集合,反而会把JSON结果作为一个名为__dict__的普通属性存入实例的属性字典中。 - 自定义
__setattr__方法拦截:如果你的类或它继承的父类中定义了自定义的__setattr__方法,那么self.__dict__ = ...的赋值操作会被该方法拦截,将__dict__当成普通属性名处理,最终JSON数据会被存在self.__dict__['__dict__']里,而非替换整个属性字典。
解决办法
可以用以下几种方式避免这个问题:
- 直接更新属性字典而非替换:不要直接赋值
__dict__,改用update方法将JSON数据合并到实例的属性字典中:
这种方式兼容性最好,不管是经典类还是新式类,也不管有没有自定义self.__dict__.update(json.load(f, encoding='utf-8-sig'))__setattr__,都能正确将JSON的键值对转为实例属性。 - 绕过自定义
__setattr__强制替换:如果必须替换整个__dict__,可以调用object的__setattr__方法绕过自定义逻辑:object.__setattr__(self, '__dict__', json.load(f, encoding='utf-8-sig')) - 统一使用新式类:在Python 2.7中显式让类继承
object,确保__dict__的行为一致:class YourClass(object): def __init__(self, f): self.__dict__ = json.load(f, encoding='utf-8-sig')
内容的提问来源于stack exchange,提问作者Patcha
相关产品推荐
相关产品推荐

