api不要返回dict
2019-01-06 本文已影响30人
ThomasYoungK
返回dict会令调用方抓狂,可以用java的bean的方式来返回,我举了几个例子
- namedtuple
- 有默认值的namedtuple子类,用partial实现
- 有默认值得namedtuple子类,正儿八经的继承重写
__new__
实现 - 继承dict并替换
__dict__
属性的类, 可以接收任意字段 - dataclass实现(python3.7引入),可以有默认字段,需要列在最后面
# 不要返回dict!!! 参考视频:[大兄弟,写Python请别返回Dict](https://www.bilibili.com/video/av20963030)
from collections import namedtuple
from typing import Dict, Optional
from attr import dataclass
SomeApiDataModel = namedtuple('SomeApiDataModel', 'field_1 field_2 field_3')
print('# --------------------------------------------------')
def some_api():
d = {}
d['field_1'] = 'abc'
d['field_2'] = 3
d['field_3'] = {
'field_3_1': 13
}
return SomeApiDataModel(**d)
ret = some_api()
print(ret)
print(ret.field_3['field_3_1'])
print(ret._asdict())
print('# --------------------------------------------------')
def some_api_v2():
d = {}
d['field_1'] = 'abc'
d['field_3'] = {
'field_3_1': 13
}
return SomeApiDataModel(**d)
from functools import partial
# ret2 = some_api_v2() # TypeError: __new__() missing 1 required positional argument: 'field_2'
SomeApiDataModel.__new__ = partial(SomeApiDataModel.__new__, field_2=None)
ret2 = some_api_v2()
print(ret2)
print('# --------------------------------------------------')
class SomeApiDataModel(namedtuple('SomeApiDataModel', 'field_1 field_2 field_3')):
def __new__(cls, field_1, field_3, field_2=1234):
return super().__new__(cls, field_1, field_2, field_3)
ret3 = some_api_v2()
print(ret3)
print('# --------------------------------------------------')
class SomeApiDataModel_V3(dict):
def __init__(self, *args, **kwargs):
self.__dict__ = kwargs
super().__init__(self, *args, **kwargs)
def some_api_v3():
d = {}
d['field_1'] = 'abc'
d['field_3'] = {
'field_3_1': 13
}
return SomeApiDataModel_V3(**d)
ret4 = some_api_v3()
print(ret4)
print(ret4.field_1)
print(ret4.field_3['field_3_1'])
print('# --------------------------------------------------')
# dataclass?
@dataclass
class SomeApiDataModel_V4:
field_1: str
field_3: Dict[str, int]
field_2: Optional[str] = None
def some_api_v4():
d = {}
d['field_1'] = 'abc'
d['field_3'] = {
'field_3_1': 13
}
return SomeApiDataModel_V4(**d)
ret5 = some_api_v4()
print(ret5)
print(ret5.field_3)
print(ret5.field_3['field_3_1'])
输出如下:
# --------------------------------------------------
SomeApiDataModel(field_1='abc', field_2=3, field_3={'field_3_1': 13})
13
OrderedDict([('field_1', 'abc'), ('field_2', 3), ('field_3', {'field_3_1': 13})])
# --------------------------------------------------
SomeApiDataModel(field_1='abc', field_2=None, field_3={'field_3_1': 13})
# --------------------------------------------------
SomeApiDataModel(field_1='abc', field_2=1234, field_3={'field_3_1': 13})
# --------------------------------------------------
{'field_1': 'abc', 'field_3': {'field_3_1': 13}}
abc
13
# --------------------------------------------------
SomeApiDataModel_V4(field_1='abc', field_3={'field_3_1': 13}, field_2=None)
{'field_3_1': 13}
13