Получить имя атрибута в цикле For - PullRequest
1 голос
/ 08 июня 2011

Как получить имена атрибутов и значения объекта? Я пытаюсь преобразовать его в словарь, чтобы я мог легко JSON-сериализовать объект.

Код:

class User:
    ...
    def to_dict( self ):
        dict = {}
        for key, value in filter( lambda aname: not aname.startswith('_'), dir(self) ):
            dict[key] = value
    return dict

Ошибка:

too many values to unpack

Использование:

user = User({
    's_email': 'bob@email.com',
    's_password': 'password',
})
user.to_dict()
# JSON Serialize

Ответы [ 3 ]

3 голосов
/ 08 июня 2011

Вы получаете эту ошибку, потому что filter( lambda aname: not aname.startswith('_'), dir(u) ) возвращает список отдельных элементов, и вы пытаетесь распаковать два значения (for key, value). Возможная причина использования dir вместо __dict__ может заключаться в том, что вы заботитесь об атрибутах класса или унаследованных атрибутах. Так как __dict__ содержит только атрибуты экземпляра, он не найдет их.

class Base(object):
    x = 1

class User(Base):
    y = 2
    def __init__(self, z):
        self.z = z

>>> u = User(3)

>>> u.__dict__
<<< {'z': 3}

Если вы хотите использовать dir still, вы можете сделать это так:

def to_dict(self):
    d = {}
    for k, v in [(x, getattr(self, x)) for x in dir(self) if not x.startswith('_')]:
        if not hasattr(v, '__call__'): d[k] = v # skip methods
    return d

>>> u = User(3)

>>> u.to_dict()
<<< {'x': 1, 'y': 2, 'z': 3}

Определение атрибутов в явном виде как в этом ответе , вероятно, будет лучшим маршрутом.

1 голос
/ 08 июня 2011

Используйте self.__dict__.Это словарь, представляющий пространство имен объекта.

class User:
    ...
    def to_dict(self):
        return dict(
            [(k, v) for k, v in self.__dict__.iteritems() if not k.startswith('_')]
        )

Обратите внимание, что, учитывая ваш фрагмент кода, dict, возвращаемый .to_dict(), будет содержать ключ 'to_dict', так как функция не начинается с подчеркивания,Вероятно, простая ошибка в вашем посте.

Если список атрибутов, которые вы хотите включить в возвращаемый dict, невелик (и не сильно меняется), я предлагаю вам четко указать это и перечислить их

class User(object):
    data_attributes = ('s_email', 's_password')
    def to_dict(self):
        return dict([(attr, getattr(self, attr) for attr in self.data_attributes])
0 голосов
/ 08 июня 2011

Я мог бы что-то упустить, но почему бы не просто user.__dict__?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...