質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

573閲覧

Pythonでフィールドにクラスオブジェクトを持つクラスをJSON形式にダンプしたい.

teriyaki0839

総合スコア8

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2023/04/02 05:08

実現したいこと

フィールドに他クラスのインスタンスを持つクラスのjsonファイル出力

前提

Pythonで以下のようなクラスA,Bがあるときに,クラスAの__dict__をダンプしようとすると
フィールドにクラスBがありObject型であるためにエラーが発生してしまします.

クラスA.__dict__をしたときに,フィールドのクラスBも.__dict__で処理できればよいのですが方法がわかりません.

発生している問題・エラーメッセージ

Traceback (most recent call last): File "test.py", line 17, in <module> json.dumps(a.__dict__) File "Python39\lib\json\__init__.py", line 231, in dumps return _default_encoder.encode(obj) File "Python39\lib\json\encoder.py", line 199, in encode chunks = self.iterencode(o, _one_shot=True) File "Python39\lib\json\encoder.py", line 257, in iterencode return _iterencode(o, 0) File "Python39\lib\json\encoder.py", line 179, in default raise TypeError(f'Object of type {o.__class__.__name__} ' TypeError: Object of type B is not JSON serializable

該当のソースコード

python

1import json 2 3class A: 4 def __init__(self, a, b): 5 self.data_a = a 6 self.class_b = b 7 8class B: 9 def __init__(self, b): 10 self.data_b = b 11 12b = B('b') 13a = A('a', b) 14json.dumps(a.__dict__)

試したこと

13行目の引数をb.__dict__にすればいいのですが,
python内部ではクラスオブジェクトのまま保持したいです.
よろしくお願いします.

補足情報(FW/ツールのバージョンなど)

  • Python 3.10.0
  • json 2.0.9

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2023/04/02 05:43 編集

※ 削除
guest

回答2

0

ベストアンサー

python

1import json 2 3class A(): 4 def __init__(self, a, b): 5 self.data_a = a 6 self.class_b = b 7 8 def to_dict(self): 9 dic = {} 10 for k, v in self.__dict__.items(): 11 try: 12 json.dumps(v) 13 except TypeError: 14 if '__dict__' in dir(v): 15 v = v.__dict__ 16 else: 17 continue 18 finally: 19 dic[k] = v 20 21 return dic 22 23class B: 24 def __init__(self, b): 25 self.data_b = b 26 27if __name__ == '__main__': 28 b = B('b') 29 a = A('a', b) 30 js = json.dumps(a.to_dict()) 31 print(js) 32 33# {"data_a": "a", "class_b": {"data_b": "b"}}

投稿2023/04/02 06:13

melian

総合スコア19618

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teriyaki0839

2023/04/02 06:32

ありがとうございましたm(_ _"m)
guest

0

BAついてますが、クラスA,Bをいじってもいいのであれば、こういう手もありますよ。

python

1import json 2 3class A(dict): 4 def __init__(self, a, b): 5 dict.__init__(self, data_a=a, class_b=b) 6 self.data_a = a 7 self.class_b = b 8 9class B(dict): 10 def __init__(self, b): 11 dict.__init__(self, data_b=b) 12 self.data_b = b 13 14b = B('b') 15a = A('a', b) 16print(json.dumps(a))

dictであれば「JSON serializable」なので、dictを継承しちゃえばいいかなと。 Aもそうしてしまえば、__dict__も不要になります。

投稿2023/04/02 08:00

TakaiY

総合スコア12666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問