api不要返回dict

2019-01-06  本文已影响30人  ThomasYoungK

返回dict会令调用方抓狂,可以用java的bean的方式来返回,我举了几个例子

  1. namedtuple
  2. 有默认值的namedtuple子类,用partial实现
  3. 有默认值得namedtuple子类,正儿八经的继承重写__new__实现
  4. 继承dict并替换__dict__属性的类, 可以接收任意字段
  5. 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
上一篇下一篇

猜你喜欢

热点阅读