python basic programming: data format converting JSON Python class object Detailed methods (both methods)

Through two ways to introduce the JSON data format to convert a Python class objects, this paper examples of code to tell you in great detail, has a certain value for references, a friend in need can refer
JOSN convert a string from define a class instance object

Sometimes we have this demand is to a JSON string into a Python class specific examples, such as you receive such a JSON string is as follows:

{"Name": "Tom", "Sex": "Male", "BloodType": "A", "Hobbies": ["篮球", "足球"]}

I need to convert this particular instance of the Person class, to be operated by means of an object. There are many implementations such as Gson or FastJosn in Java. As shown in the following code (here not all of the code, the main value of the identification part):

import com.alibaba.fastjson.JSONObject;
import com.example.demo.entity.Product;
String a = "{\"gmtCreate\":1559009853000,\"dataFormat\":1,\"deviceCount\":1,\"nodeType\":0,\"productKey\":\"a1U85pSQrAz\",\"productName\":\"温度计\"}";
//JSON字符串反序列化为一个Product对象
Product product = JSONObject.parseObject(a, Product.class);

This generally occurs in the above-described requirements when passing over the pre-stage JSON string or other systems is also transmitted over the communication RPC JSON string, as a receiver requires deserialized into objects to be treated, but there are still a JSONArray.parseArray method Fastjson It can be converted to a list of objects. But in Java, Python did not like such a convenient thing.

From Groups also seen some, but many are there but the effect of using up trouble, so I'm here for my ideas.

Mode 1: realized by josn.loads

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import json
class Person:
 def __init__(self, data=None):
  self._name = "1"
  self._sex = ""
  self._blood_type = "O"
  self._hobbies = []
  self._date_of_birth = "1900/1/1"
  if data:
   self.__dict__ = data
 # 通过属性的方式来获取和设置实例变量的值,如果不这样那么就只能通过set或者get方法来做
 @property
 def date_of_brith(self):
  return self._date_of_birth
 @date_of_brith.setter
 def date_of_brith(self, date_of_brith):
  self._date_of_birth = date_of_brith
def main():
 try:
  str1 = '{"name": "Tom", "sex": "male", "blood_type": "A", "hobbies": ["篮球", "足球"]}'
  person1 = json.loads(str1, object_hook=Person)
  print(isinstance(person1, Person))
  # 这里你会发现没有date_of_brith这个内容
  print(person1.__dict__)
  # 获取date_of_brith属性值报错,因为JSON字符串不包含这个键,但是类中的实例变量有这个,正常来讲你应该可以获取默认值,但是由于
  # 替换了__dict__,所以就没有了,因为__dict__原本就是实例变量的字典形式,你替换了自然也就找不到原来的了。
  # print(person.date_of_brith)
  # 下面我们通过正常的方式实例化一个对象
  person2 = Person()
  print(person2.__dict__)
  print(person2.date_of_brith)
 except Exception as err:
  print(err)
if __name__ == "__main__":
 try:
  main()
 finally:
  sys.exit()

object_hook meaning that the default json.loads () returns a dict, you can use object_hook be allowed to return other types of values, it's the principle here is to realize that you passed in JSON string passed to the method specified object_hook or class (if it is the kind of thing will be executed __init__ method is actually instantiated), this time in the method __init class assigned to us by self.dict__, in fact, which is equal to the Person class instance variables do replacement, unless the name and number of keys and instance variables of your JSON string of consistent otherwise you can not pass your name instance variable defined in the class to get the value passed in through a JSON string. FIG follows: Here Insert Picture Description
So it can be seen from the above, this process is not assigned to process the instance variables, but an alternative process, Python dynamic language that is different and JAVA. If you work for a private (just specifications rather than true private) in the program are underlined with a single variable that JSON string you pass keys also underlined the need, so you can get through a method instance. Since the extra underscore is not realistic, then there is no other way to do it? Look at the way 2

Embodiment 2: reflection achieved by

Look at the definition of the class

#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Person:
 def __init__(self):
  self._name = "1"
  self._sex = ""
  self._blood_type = "O"
  self._hobbies = []
  self._date_of_birth = "1900/1/1"
 def __str__(self):
  """
  输出实例的类名字,而不是一个地址
  :return: 该实例的类名字
  """
  return self.__class__.__name__
 # 当一个方法加上这个装饰器之后,hasattr()中的属性要写成这个方法的名称,而不是实例变量的名称。
 # 如果不加这个装饰器,那么hasattr()中的属性名称要和实例变量的名称保持一致
 @property
 def Name(self):
  return self._name
 @Name.setter
 def Name(self, name):
  self._name = name
 @property
 def Sex(self):
  return self._sex
 @Sex.setter
 def Sex(self, sex):
  self._sex = sex
 @property
 def BloodType(self):
  return self._blood_type
 @BloodType.setter
 def BloodType(self, blood_type):
  self._blood_type = blood_type
 @property
 def Hobbies(self):
  return self._hobbies
 @Hobbies.setter
 def Hobbies(self, hobbies):
  self._hobbies = hobbies
 @property
 def date_of_brith(self):
  return self._date_of_birth
 @date_of_brith.setter
 def date_of_brith(self, date_of_brith):
  self._date_of_birth = date_of_brith

Let's look at the method of conversion

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import json
import importlib
def get_instance(str_stream, class_full_path=None):
 """
 :param str_stream: json的字符串形式 '{"Name": "Tom", "Sex": "Male", "BloodType": "A"}'
 :param class_full_path: package.module.class
 :return:
 """
 try:
  json_obj = json.loads(str_stream)
 except Exception as err:
  print("输入的字符串不符合JSON格式,请检查。")
  return None
 if class_full_path is None:
  return json_obj
 else:
  try:
   # 获取模块路径
   module_path = ".".join(class_full_path.split(".")[0:-1])
   # 获取类名称
   class_name = class_full_path.split(".")[-1]
   # 通过模块名加载模块
   CC = importlib.import_module(module_path)
   # 判断是否有class_name所代表的属性
   if hasattr(CC, class_name):
    # 获取模块中属性
    temp_obj = getattr(CC, class_name)
    # 实例化对象
    obj = temp_obj()
    for key in json_obj.keys():
     obj.__setattr__(key, json_obj[key])
    return obj
   else:
    pass
  except Exception as err:
   print(err)
   return None
def main():
 try:
  str1 = '{"Name": "Tom", "Sex": "Male", "BloodType": "A", "Hobbies": ["篮球", "足球"]}'
  person1 = get_instance(str1, class_full_path="AAA.Classes.Person")
  # 查看类型
  print(type(person1))
  # 查看属性
  print(person1.__dict__)
  # 查看指定属性
  print(person1.Name)
 except Exception as err:
  print(err)
if __name__ == "__main__":
 try:
  main()
 finally:
  sys.exit()

Import () has two parameters, one is the first class, the second is fromlist, fromlist if not write, the writing will be introduced in the following only AAA packet, the value will be introduced if there fromlist following Classes AAA module cc = Import ( "AAA.Classes", fromlist = True) do not write fromlist equivalent to import AAA, if writing is equivalent to import Classes are from AAA when programming with dynamic load recommended importlib.import_module (), rather than __import __ () .

Let's look at the results Here Insert Picture Description
you can see, after this operation is to give an instance variable assignment like that, but not before replacement, but retained the private specification class instance variables. But JSON string is the key to the attribute name and the name of the class defined inside the same should be noted, that is the key name to the class @property and decorative methods of the same name. We can also see that this use is also the default JSONObject.parseObject meaning.

But this is only a simple implementation, not only to generate a list of objects generated by a single JSON string object. Of course, interested friends can be extended based on this idea.

In addition, since both the loads or my own search methods need to ensure a JSON string key and variable names consistent we do not tangle in the name of the same problem, but my approach did it keep the instance variable named instance attribute practices of the time, class while not too much unlike loads invasive method is also a need to increase the content in which an unnecessary class init method. In this method, if I can achieve universal ignore case better. Welcome everyone to provide ideas.
I write to you, for everyone to recommend a very wide python learning resource gathering, click to enter , there is a senior programmer before learning to share experiences, study notes, there is a chance of business experience, and for everyone to carefully organize a python zero the basis of the actual project data, daily python to you on the latest technology, prospects, learning the small details need to leave a message
summary

The above is a small series to introduce you to convert JSON data format for the class of object methods Python Hi, we want to help, if you have any questions please give me a message, Xiao Bian will promptly reply to your

Published 50 original articles · won praise 34 · views 70000 +

Guess you like

Origin blog.csdn.net/haoxun08/article/details/104909410