Pythonにおけるクラスの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}