4

クラス デコレータを使用して Python でカスタム オブジェクトを dict にエンコードし、結果の dict に引数として含める必要がある変数の名前を提供する方法を探しています。json.dumps(custom_object_dict)dict を使用すると、JSON への変換に使用できます。

言い換えれば、アイデアは次の@encoderクラスデコレータを持つことです:

@encoder(variables=['firstname', 'lastname'], objects=['professor'], lists=['students'])
class Course(Object):
   def __init__(self, firstname, lastname, professor, students):
        self.firstname = firstname
        self.lastname = lastname
        self.professor = professor
        self.students = students

#instance of Course:
course = Course("john", "smith", Professor(), [Student(1), Student(2, "john")])

このデコレーターを使用すると、次のようなことができます。

オプション A:

json = json.dumps(course.to_dict())

オプション B:

json = json.dumps(course.dict_representation)

...またはそのようなもの

問題は、このエンコーダーの書き方です。実際の要件は次のとおりです。

  1. エンコーダーは、デコレーターを介して提供される変数のみをエンコードする必要があります
  2. エンコーダーは他のオブジェクトをエンコードできる必要があります (例: 教授クラスにデコレータもある場合、コース内の教授)@encoder
  3. また、他のオブジェクトのリストをエンコードできる必要があります (例: コース内の学生、そのクラスの学生も@encoderデコレータにする必要があることをカウント)

私はそれを行うさまざまな方法(json.JSONEncoderから継承するクラスの作成を含む)を調査しましたが、私が考えていたことを正確に行うものはありませんでした。誰でも私を助けることができますか?

前もって感謝します!

4

1 に答える 1

2

たぶん、次のようなものです(簡単なスケッチです):

#! /usr/bin/python3.2

import json

class Jsonable:
    def __init__ (self, *args):
        self.fields = args

    def __call__ (self, cls):
        cls._jsonFields = self.fields
        def toDict (self):
            d = {}
            for f in self.__class__._jsonFields:
                v = self.__getattribute__ (f)
                if isinstance (v, list):
                    d [f] = [e.jsonDict if hasattr (e.__class__, '_jsonFields') else e for e in v]
                    continue
                d [f] = v.jsonDict if hasattr (v.__class__, '_jsonFields') else v
            return d
        cls.toDict = toDict

        oGetter = cls.__getattribute__
        def getter (self, key):
            if key == 'jsonDict': return self.toDict ()
            return oGetter (self, key)
        cls.__getattribute__ = getter

        return cls

@Jsonable ('professor', 'students', 'primitiveList')
class Course:
    def __init__ (self, professor, students):
        self.professor = professor
        self.students = students
        self.toBeIgnored = 5
        self.primitiveList = [0, 1, 1, 2, 3, 5]

@Jsonable ('firstname', 'lastname')
class Student:
    def __init__ (self, firstname, lastname, score = 42):
        self.firstname = firstname
        self.lastname = lastname
        self.score = score

@Jsonable ('title', 'name')
class Professor:
    def __init__ (self, name, title):
        self.title = title
        self.name = name

p = Professor ('Ordóñez', 'Dra')
s1 = Student ('Juan', 'Pérez')
s2 = Student ('Juana', 'López')
s3 = Student ('Luis', 'Jerez')
s4 = Student ('Luisa', 'Gómez')
c = Course (p, [s1, s2, s3, s4] )

print (json.dumps (c.jsonDict) )

if以外の iterablelistや何かをチェックしたいかもしれませんhasattr (v, __iter__) and not isinstance (v, str)

于 2013-02-16T03:18:35.480 に答える