缘起
话接上回,说是接手了一个82年的拉菲Python项目,这次又发现了一个新坑
项目中用了一个上下文类,用于存储本次请求的一些数据,在开发过程中我想把这个上下文类dump成json,详细分析里面的数据,然而发现上下文类的行为不符合预期
症状
上下文类大概是这样
1 | class Context(): |
测试之后发现,结果明显不符合预期,两个属性只输出了一个1
2
3
4
5
6
7
8from test_property import Context
c = Context()
c.input_json = {'a': 1}
c.result_dict['b'] = 2
...
get _result_dict
c.to_dict()
{'_input_json': None, '_result_dict': {'b': 2}}
分析
看测试代码我们可以发现,在访问result_dict属性的时候,property是工作正常的(有对应的print)
但是对应设置input_json的时候, 却没有看到对应的print输出
所以可以断定,此处的property工作不正常。
仔细看代码后,我发现Context是旧式类。可以看到,A, B, C三中类的写法,其中A和B都是旧式类<type 'classobj'>, C是新式类。(旧式类只在Python2中存在)。
我们这里Context的写法和B是一样的。
1 | class A: |
然后自然就怀疑旧式类对property装饰器的支持存在问题。
一通google之后,确定旧式类是不支持property。

确切地说,是对property的支持不完整,具体来说有以下3点。
- 支持property的getter
- 不支持property的setter
- 不支持property的赋值保护