Несоответствие объектов - PullRequest
       10

Несоответствие объектов

3 голосов
/ 20 сентября 2011

Я пишу на python некоторые json-кодеры для производного от словаря класса EPPI_dictDB, объект этого класса может быть сохранен как значение некоторых экземпляров синтаксического анализатора класса.

НО, когда я что-то кодирую, происходит что-то не так, и экземпляр класса EPPI_dictDB, переданный конкретной функции кодера, становится экземпляром синтаксического анализатора класса!

Позвольте мне объяснить лучше на примере. Если я выполню этот код

import json
import raw.data_input as data_input
p = data_input.parser()
class data():
    def __str__(self):
        return self.name

data1 = data()
data1.name = "data1"
data1.proteins = ['acc1','acc2']
data1.peptides = [('acc1',['SEQTWO']),
                      ('acc2',['SEQONE'])]
p.parse(data1)
s = EPPI_dbopen('tmp.prj', flag='n')
s["parser"] = p

print s.__class__
print isinstance(s, EPPI_DictDB)
print isinstance(s, data_input.parser)

Я получаю эти результаты:

<class '__main__.EPPI_DictDB'>
True
False

после того, как я вызову кодировщик:

print json.dumps(obj=s, cls=projectEncoder)

Внутри кода кодирования я поместил несколько «отпечатков», чтобы определить природу передаваемого объекта:

class projectEncoder(json.JSONEncoder):
    def default(self, obj):

        print obj.__class__
        print isinstance(obj, EPPI_DictDB)
        print isinstance(obj, data_input.parser)

        if isinstance(obj, EPPI_DictDB):
            result = obj.__dict__
            if "parser" in result.keys():
                pars = result["parser"]
                result["parser"] = parserEncoder().encode(pars)
            if "selected" in results.keys():
                sel = result["selected"]
                result["selected"] = parserEncoder().encode(sel)
            return result
        return json.JSONEncoder.default(self, obj)

Результаты внутренних отпечатков:

<class 'raw.data_input.parser'>
False
True

Может ли кто-нибудь объяснить мне, что случилось?

1 Ответ

0 голосов
/ 20 сентября 2011

немного догадываясь:

Кодеры JSON уже знают, как обрабатывать дикты, поэтому он обрабатывает ваш подкласс dict так же, как и dict. Однако, когда он достигает s ["parser"], он не знает, что делать с объектом, поэтому он вызывает для него ваш метод default. То есть из вашего кода он видит p, а не s.

Кажется, это то, что документы говорят.

EDIT

Глядя на то, что вы на самом деле делаете, я думаю, что должен быть более простой способ достичь этого:

def default(self, obj):
    if isinstance(obj, data_input.parser):
        return parserEncoder().encode(obj)
    return super(projectEncoder, self).default(obj)

Если поле "selected" относится к другому типу, просто измените вторую строку на:

if isinstance(obj, (data_input.parser, type_of_selected)):
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...