【问题标题】:JSON to Python objectsJSON 到 Python 对象
【发布时间】:2018-06-15 19:34:39
【问题描述】:

我正在考虑如何将复杂信息从 JSON API 响应传输到(几个)Python 对象。我在下面包含了(冗长的)模型响应。请注意,有些值并不总是包含在响应中,有些值是字典列表。

是否有一种“简单”的方法可以将 JSON 响应映射到 Python 对象?理想情况下,我将如何布置课程?

模型 JSON 响应:

{
   "accounts" : {
      "accounting_reference_date" : {
         "day" : "integer",
         "month" : "integer"
      },
      "last_accounts" : {
         "made_up_to" : "date",
         "period_end_on" : "date",
         "period_start_on" : "date",
         "type" : "string"
      },
      "next_accounts" : {
         "due_on" : "date",
         "overdue" : "boolean",
         "period_end_on" : "date",
         "period_start_on" : "date"
      },
      "next_due" : "date",
      "next_made_up_to" : "date",
      "overdue" : "boolean"
   },
   "annual_return" : {
      "last_made_up_to" : "date",
      "next_due" : "date",
      "next_made_up_to" : "date",
      "overdue" : "boolean"
   },
   "branch_company_details" : {
      "business_activity" : "string",
      "parent_company_name" : "string",
      "parent_company_number" : "string"
   },
   "can_file" : "boolean",
   "company_name" : "string",
   "company_number" : "string",
   "company_status" : "string",
   "company_status_detail" : "string",
   "confirmation_statement" : {
      "last_made_up_to" : "date",
      "next_due" : "date",
      "next_made_up_to" : "date",
      "overdue" : "boolean"
   },
   "date_of_cessation" : "date",
   "date_of_creation" : "date",
   "etag" : "string",
   "external_registration_number" : "string",
   "foreign_company_details" : {
      "accounting_requirement" : {
         "foreign_account_type" : "string",
         "terms_of_account_publication" : "string"
      },
      "accounts" : {
         "account_period_from" : {
            "day" : "integer",
            "month" : "integer"
         },
         "account_period_to" : {
            "day" : "integer",
            "month" : "integer"
         },
         "must_file_within" : {
            "months" : "integer"
         }
      },
      "business_activity" : "string",
      "company_type" : "string",
      "governed_by" : "string",
      "is_a_credit_finance_institution" : "boolean",
      "originating_registry" : {
         "country" : "string",
         "name" : "string"
      },
      "registration_number" : "string"
   },
   "has_been_liquidated" : "boolean",
   "has_charges" : "boolean",
   "has_insolvency_history" : "boolean",
   "is_community_interest_company" : "boolean",
   "jurisdiction" : "string",
   "last_full_members_list_date" : "date",
   "links" : {
      "charges" : "string",
      "filing_history" : "string",
      "insolvency" : "string",
      "officers" : "string",
      "persons_with_significant_control" : "string",
      "persons_with_significant_control_statements" : "string",
      "registers" : "string",
      "self" : "string"
   },
   "partial_data_available" : "string",
   "previous_company_names" : [
      {
         "ceased_on" : "date",
         "effective_from" : "date",
         "name" : "string"
      }
   ],
   "registered_office_address" : {
      "address_line_1" : "string",
      "address_line_2" : "string",
      "care_of" : "string",
      "country" : "string",
      "locality" : "string",
      "po_box" : "string",
      "postal_code" : "string",
      "premises" : "string",
      "region" : "string"
   },
   "registered_office_is_in_dispute" : "boolean",
   "sic_codes" : [
      "string"
   ],
   "subtype" : "string",
   "type" : "string",
   "undeliverable_registered_office_address" : "boolean"
}

【问题讨论】:

    标签: python json api class object


    【解决方案1】:

    如果我理解正确,并且您想获取一个 json 对象并将其抽象为一个类,您可以使用一个类和 setattr() 来做到这一点。

    这会遍历json中的每个key,如果key的值不是dict,它会将属性(带有key的名字)设置为value。

    如果键的值是dict,它会创建一个JsonToObject的新实例,并使用新对象重复上述过程,并设置JsonToObject 的新实例的属性(带有原始键的名称)。

    import json
    
    class JsonToObject:
    
        def __init__(self, json_object):
            self.json_object = json_object
            self.keys = json_object.keys()
            self.setup(json_object)
    
        def setup(self, d):
            for key, item in d.items():
                if isinstance(item, dict):
                    new_object = JsonToObject(item)
                    setattr(self, key, new_object)
                else:
                    setattr(self, key, item)
    
    # I am reading from a file with the contents you specified.
    # If you are reading the json from a variable instead of a file,
    # take away the `with open...` line and use 
    # `d = json.loads(json_content)` instead of `d = json.load(f)`
    with open("test.json", "rb") as f:
        d = json.load(f)
    
    json_obj = JsonToObject(d)
    
    print(json_obj.accounts.accounting_reference_date.day)
    print(json_obj.annual_return.next_due)
    

    否则,如果你只想将json加载到内存中并像python字典一样访问它:

    import json
    
    with open("test.json", "rb") as f:
        d = json.load(f)
    
    print(d["accounts"]["accounting_reference_date"]["day"])
    print(d["annual_return"]["next_due"])
    

    两个示例都给出相同的输出:

    integer
    date
    

    【讨论】:

      【解决方案2】:

      Python 提供了一个json 模块,您可以通过该模块将数据从JSON“加载”到Python。在这个例子中,如果 response 是一个代表你的 JSON 大块的变量,你可以这样做:

      import json
      py_object_collection = json.loads(response)
      

      如果这对您不起作用,则需要您在问题中指定预期的输出结果。

      【讨论】:

        猜你喜欢
        • 2020-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        • 1970-01-01
        • 2019-07-04
        • 2018-01-01
        相关资源
        最近更新 更多