从restapi返回的JSON动态创建Python对象

2024-03-28 09:28:32 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有两个restapi端点(http://example.com/taskhttp://example.com/employee)和以下两个类:

class Employee(object):
    def __init__(self, **kwargs):
        self.ID = kwargs['ID']
        self.first_name = kwargs['first_name'] if 'first_name' in kwargs else None
        self.last_name = kwargs['last_name'] if 'last_name' in kwargs else None

class Task(object):
    def __init__(self, **kwargs):
        self.ID = kwargs['ID']
        self.start_date = kwargs['start_date']
        self.employee = Employee(ID=kwargs['employee_id'])

现在我想从restapi返回的json创建Python对象。在

假设GET to http://example.com/task/19返回以下json:

^{pr2}$

现在,下面所有的工作

print(task.ID) # 19
print(task.start_date) # 2018-04-23
print(task.employee.ID) # xyz1223

但是print(task.employee.first_name)返回None。我希望的是,在幕后发送一个对http://example.com/employee/xyz1223的GET请求,解析得到的json,并填充属性first_name和{}。在

最像Python的方式是什么?在


Tags: nameselfcomnoneidhttptaskdate
1条回答
网友
1楼 · 发布于 2024-03-28 09:28:32

我会让__init__方法尽可能简单和愚蠢, 这意味着noI/O。这项工作被推迟到名为from_api的类方法,该方法只将请求的ID作为参数,然后构建适当的URI,解析输出,并将必要的数据传递给 对__init__的调用。在

Employee.from_api仍然非常简单,但是Task.from_api是通过调用Employee.from_api来实现“join”的,参数取自解析的任务JSON数据。在

class Employee(object):
    BASE_URL = "http://example.com/employee/"

    def __init__(self, id_, first, last):
        self.id_ = id_
        self.first_name = first
        self.last_name = last

    @classmethod
    def from_api(cls, id_):
        url = cls.BASE_URL + id_
        json_data = requests.get(url).json()
        return Employee(id_=id_
                        first=json_data.get('first_name'),
                        last=json_data.get('last_name'))


class Task(object):
    BASE_URL = "http://example.com/task/"

    def __init__(self, id_, start_date, emp):
        self.ID = id_
        self.start_date = start_date
        self.employee = emp

    @classmethod
    def from_api(cls, id_):
        url = cls.BASE_URL + id_
        json_data = requests.get(url).json()
        emp = Employee.from_api(json_data['employee_id'])
        return Task(id_, json_data['start_date'], emp)


task = Task.from_api("19")

这样的设计非常适合Python3.7即将发布的data classes

^{pr2}$

相关问题 更多 >