PythonにおけるクラスのJSONシーケンス化
これはきっとありふれた問題に違いない.ここに記録しておく.
Pythonではsqlalchemyを使用していますormがデータベース・オブジェクトにアクセスし、これらのデータをフロント・ページに表示すると、Pythonのクラス・オブジェクトをJSONシーケンス化する方法に直面します.
簡単に言えば、コードから言えば、
まず、ユーザー情報を格納するユーザークラスを定義します.
ユーザオブジェクトuser 1をインスタンス化し、JSONシーケンス化dumps操作を直接行う
エラーメッセージ:
TypeError: Object of type ‘User’ is not JSON serializable
Userオブジェクトは直接シーケンス化できません.dumpsメソッドの定義を参照してください.
defaultパラメータは次のように定義されています.
そこで、Userオブジェクトにシーケンス化方法を指定します.
dumpsメソッドを再実行すると、次の結果が得られます.
{“id”: 1, “name”: “test”, “password”: “password”}
もちろん、Pythonではdict_クラスのすべての属性を含む特殊な属性です.そのため、Userオブジェクトに次のパラメータを指定することもできます.
json.dumps(user1, default=lambda obj: obj.dict)
再実行すると、次の結果が得られます.
{“_User__id”: 1, “_User__name”: “test”, “_User__password”: “password”}
次のようにTeacherクラスを再定義するとします.
Userクラスとは少し違いますが、私たちは_slots_組み込み属性はオブジェクトTeacherがaddressとgrade属性のみを持つことを制限し、メソッドを再実行します.
json.dumps(teacher, default=lambda obj: obj.dict)
エラーメッセージ:
AttributeError: ‘Teacher’ object has no attribute ‘dict’
使用_slots_制限されたクラスがありません_dict_属性ですので、TeacherクラスのJSONシーケンス化方法を独自に実装する必要があります.
Pythonではsqlalchemyを使用していますormがデータベース・オブジェクトにアクセスし、これらのデータをフロント・ページに表示すると、Pythonのクラス・オブジェクトをJSONシーケンス化する方法に直面します.
簡単に言えば、コードから言えば、
まず、ユーザー情報を格納するユーザークラスを定義します.
class User(object):
def __init__(self, id, name, password):
self.__id = id
self.__name = name
self.__password = password
def __repr__(self):
return "id is %s, name is %s, password is %s" % (self.__id, self.__name, self.__password)
def get_name(self):
return self.__name
def get_password(self):
return self.__password
def get_id(self):
return self.__id
ユーザオブジェクトuser 1をインスタンス化し、JSONシーケンス化dumps操作を直接行う
user1 = User(1, 'test', 'password')
print(user1)
#
print(json.dumps(user1))
エラーメッセージ:
TypeError: Object of type ‘User’ is not JSON serializable
Userオブジェクトは直接シーケンス化できません.dumpsメソッドの定義を参照してください.
def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw):
defaultパラメータは次のように定義されています.
default(obj)
is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. そこで、Userオブジェクトにシーケンス化方法を指定します.
def user_to_str(user):
return {'id': user.get_id(), 'name': user.get_name(), 'password': user.get_password()}
dumpsメソッドを再実行すると、次の結果が得られます.
{“id”: 1, “name”: “test”, “password”: “password”}
もちろん、Pythonではdict_クラスのすべての属性を含む特殊な属性です.そのため、Userオブジェクトに次のパラメータを指定することもできます.
json.dumps(user1, default=lambda obj: obj.dict)
再実行すると、次の結果が得られます.
{“_User__id”: 1, “_User__name”: “test”, “_User__password”: “password”}
次のようにTeacherクラスを再定義するとします.
class Teacher(object):
__slots__ = ('address', 'grade')
def __repr__(self):
address = None
grade = None
if hasattr(self, 'address'):
address = self.address
if hasattr(self, 'grade'):
grade = self.grade
return "address is %s, grade is %s" % (address, grade)
Userクラスとは少し違いますが、私たちは_slots_組み込み属性はオブジェクトTeacherがaddressとgrade属性のみを持つことを制限し、メソッドを再実行します.
json.dumps(teacher, default=lambda obj: obj.dict)
エラーメッセージ:
AttributeError: ‘Teacher’ object has no attribute ‘dict’
使用_slots_制限されたクラスがありません_dict_属性ですので、TeacherクラスのJSONシーケンス化方法を独自に実装する必要があります.
def teacher_to_str(teacher):
address = ''
grade = ''
if hasattr(teacher, 'address'):
address = teacher.address
if hasattr(teacher, 'grade'):
grade = teacher.grade
return {'address': address, 'grade': grade}