Найти - Пользователи
Полная версия: преобразовать dict в объект
Начало » Python для экспертов » преобразовать dict в объект
1 2
axe
чтобы преобразовать dict в объект можно создать класс
class l_Class: pass
создать объект класса
l_Object = l_Class()
а далее для l_Object использовать:
setattr( l_Object, “aa”, “bb” )
и можно обращаться
print l_Object.aa

есть ли способ по-лучше?
Ferroman
Вообще-то в питоне словарь и так объект.
shiza
так как класс утсроен так что его атрибуты лежат в словаре (dict), можно просто проапдейтить этот словарь.
d = {'aa':'bb', 'cc':'dd'}

class l_Class: pass
l_Object = l_Class()

l_Object.__dict__.update(d)

print l_Object.aa
print l_Object.cc
или изнутри класса:
d = {'aa':'bb', 'cc':'dd'}

class l_Class:
def __init__(self, init_d):
self.__dict__.update(init_d)

l_Object = l_Class(d)

print l_Object.aa
print l_Object.cc
Александр Кошелев
до кучи
import new

d = {'aa':'bb', 'cc':'dd'}

class l_Class: pass

obj = new.instance(l_Class, d)
но конструктор не вызовется.
shiza
Если уж пошла такая пьянка ;)
import new

d = {'aa':'bb', 'cc':'dd'}

a = new.classobj('l_class', (object,), d)
Ferroman
Интересно, а какой путь Ъ?
shiza
Есть кстати еще вариант, он инетресен тем, что при изменении словаря (например добавить чтонидь) атрибуты класса тоже будут изменяться:
import new

d = {'aa':'bb', 'cc':'dd'}

class c: pass
o = c()

o.__dict__ = d

d['kk'] = 23

print o.kk
shiza
Ferroman
Интересно, а какой путь Ъ?
Наверное завист от задачи.
Если нужно одномоментно добавить в уже готовый объект атрибутов, то obj.__dict__.update мне кажется наименее магическим.
crchemist
Так працює:
>>> myClassObj = type('MyClass', (), {})()
>>> myClassObj.__dict__ = {'attr': 10}
>>> myClassObj.attr
10
Але з приватними атрибутами таке:
>>> myClassObj.__dict__ = {'__attr': 10}
>>> myClassObj.__attr
10
чи є то добре? думаю шо ні. Цікаво що таке теж працює:
>>> myClassObj = type('MyClass', (), {'__attr':10})()
>>> myClassObj.__attr
10
pikhovkin
Задача: преобразовать dict в объект и обращаться к ключам как к атрибутам.

Может кто-нибудь знает, почему этот код работает,
# -*- coding: UTF-8 -*-

class AttrInit(type):
def __call__(cls, **kwargs):
obj = super(AttrInit, cls).__call__()
for name, value in kwargs.items():
if isinstance(value, dict):
setattr(obj, name, cls(**value))
else:
setattr(obj, name, value)
return obj


class Message(object):
__metaclass__ = AttrInit

D = {'type': u'text', 'text': u'text body', 'val': {'id': {'code': 50}}}

msg = Message(**D)
print(msg.type)
print(msg.val.id.code)
а этот код, если хоть один ключ или все ключи будут типа юникод, не работает?
# -*- coding: UTF-8 -*-

class AttrInit(type):
def __call__(cls, **kwargs):
obj = super(AttrInit, cls).__call__()
for name, value in kwargs.items():
if isinstance(value, dict):
setattr(obj, name, cls(**value))
else:
setattr(obj, name, value)
return obj


class Message(object):
__metaclass__ = AttrInit

D = {u'type': u'text', u'text': u'text body', u'val': {u'id': {u'code': 50}}}

msg = Message(**D)
print(msg.type)
print(msg.val.id.code)
Выдает ошибку: TypeError: __call__() keywords must be strings
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB