Pythonの基本的なプログラミング:データフォーマット変換JSON Pythonのクラスのオブジェクトの詳細な方法(両方の方法)

Pythonのクラスオブジェクトを変換するJSONデータ形式を導入するための2つの方法を通じて、コードのこの論文の例は非常に詳細にあなたを伝えるために、参照のための一定の値を持つ、参照することができ困っている友達
JOSNは、文字列からの変換しますクラスのインスタンスオブジェクトを定義

時々、私たちは、あなたがそのようなJSON文字列を受け取るなど、この需要はPythonのクラスの具体的な例にJSON文字列にある必要があり、次のとおりです。

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

私は、オブジェクトによって操作されるように、Personクラスのこの特定のインスタンスを変換する必要があります。こうしたJavaでGsonまたはFastJosnなど多くの実装があります。(ここではなく、すべてのコード、識別部の主値)は、次のコードに示すように:

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);

これは、受信機が処理すべきオブジェクトにデシリアライズ必要に応じて、一般的に、通信RPC JSON文字列を介して送信される前段JSON文字列または他のシステムを通過する上記要件で生じるが、それでもJSONArray.parseArray方法Fastjsonありますこれは、オブジェクトのリストに変換することができます。しかし、Javaでは、Pythonは、このような便利なものを好きではなかったです。

グループはまた、いくつかのを見たが、多くはありますが、私は私のアイデアのためにここにいるので、トラブルを用いた場合の効果から。

モード1: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デフォルトjson.loads()は辞書を返すことを意味し、あなたはそれは原則はここだ、あなたがメソッド指定object_hookに渡されたJSON文字列に渡されたことを認識することで、値の他のタイプを返すことが許されobject_hook使用することができますまたはクラス(それがものの一種である場合__init__メソッドが実際にインスタンス化され実行されます)、クラスのインスタンス変数が何人に等しい実際には、self.dict__によって私たちに割り当てられたメソッド__initクラス、この時間キーと一貫性のあなたのJSON文字列のインスタンス変数の名前と番号がそうでなければ、あなたの名前のインスタンス変数は、JSON文字列経由で渡された値を取得するには、クラスで定義されて渡すことができない場合を除き、交換、。:図は、以下のここに画像を挿入説明
ことが上記から理解できるように、このプロセスは、インスタンス変数を処理するために割り当てられていない、異なるおよびJAVAである、代替プロセス、Pythonの動的言語。あなたがプログラムにプライベート(単なる仕様ではなく、真のプライベート)のために働く場合は、キーを渡すJSON文字列も必要性を強調したので、あなたは、メソッドのインスタンスを介して取得することができ、単一の変数で下線が引かれています。余分なアンダースコアが現実的ではないので、それを行うには、他の方法はありませんか?道を見てください2

実施例2:反射することによって達成

クラスの定義を見てください

#!/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

変換の方法で見てみましょう

#!/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()

インポート()は、2つのパラメータがあり、一つは、第二のfromlist、fromlistない場合、書き込み最初のクラスである、書き込みが以下のみAAAパケットに導入され、値が導入される次のクラスがfromlist場合AAAモジュールCC = インポートではなく__importより(「AAA.Classes」、fromlist =真)書き込みが輸入クラスと同等である場合には、AAAをインポートするfromlist相当するものを書いていない動的な負荷をプログラミングする際にAAAからです(importlib.import_moduleを推奨)、__() 。

結果で見てみましょうがここに画像を挿入説明
、あなたは、この操作は、そのようなインスタンス変数の割り当てを与えることです後、参照ではなく、交換の前に、しかし、民間の仕様クラスのインスタンス変数を保持することができます。しかし、JSON文字列は、属性名のキーとクラス@propertyと同じ名前の装飾方法にキー名であるに注意すべき同じ内部で定義されたクラスの名前です。また、この使用はまた、デフォルトJSONObject.parseObjectの意味であることがわかります。

しかし、これは、単一のJSON文字列オブジェクトによって生成されたオブジェクトのリストを生成するだけではなく、単純な実装です。もちろん、興味のある友人は、この考えに基づいて拡張することができます。

また、以来、負荷や私自身の検索方法の両方が、我々は同じ問題の名前でもつれませんが、私のアプローチは、それが時間のインスタンス属性の実践という名前のインスタンス変数を保持した一貫性のJSON文字列のキーと変数名を確認する必要があり、クラスも過言ではないとは異なり、負荷侵襲的な方法は、また、不必要なクラスのinitメソッドでコンテンツを増やす必要がある一方で。この方法では、私はより良いケースを無視ユニバーサル達成することができます。ようこそ誰もがアイデアを提供します。
誰もが、リソースの収集を学ぶ非常に広いのpythonをお勧めし、ために私は、あなたへの書き込み入力する]をクリックし、共有の経験に学ぶ前に、上級プログラマがあり、研究ノート、ビジネス経験の可能性がある、と皆のために注意深くのpythonゼロを整理します細部を学ぶ実際のプロジェクトデータ、最新の技術上のあなたに、毎日のpython、見通しの根拠は、メッセージのままにしておく必要があり
要約を

上記のオブジェクトのメソッドのPythonのHiのクラスのためのJSONデータ形式を変換するためにあなたを紹介する小さなシリーズで、我々はあなたが何か質問が私にメッセージをお願いしている場合は、小扁は、速やかにあなたに返信させていただきます、助けたいです

公開された50元の記事 ウォン称賛34 ビュー70000 +

おすすめ

転載: blog.csdn.net/haoxun08/article/details/104909410