Я хочу создать динамический объект (в другом объекте) в Python и затем добавить атрибуты к нему.
Я попробовал:
obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')
но это не работало.
Какие-либо идеи?
править:
Я устанавливаю атрибуты от a for
цикл, который циклы через список значений, например.
params = ['attr1', 'attr2', 'attr3']
obj = someobject
obj.a = object()
for p in params:
obj.a.p # where p comes from for loop variable
В вышеупомянутом примере я добрался бы obj.a.attr1
, obj.a.attr2
, obj.a.attr3
.
Я использовал setattr
функционируйте, потому что я не знал, как сделать obj.a.NAME
от a for
цикл.
Как я установил бы атрибут на основе значения p
в примере выше?
Вы можете использовать мой древний рецепт Bunch , но если вы не хотите создавать «класс связки», очень простой уже существует в Python - все функции могут иметь произвольные атрибуты (включая лямбда-функции). Итак, работает следующее:
obj = someobject
obj.a = lambda: None
setattr(obj.a, 'somefield', 'somevalue')
Будет ли потеря ясности по сравнению с почтенным рецептом Bunch
в порядке, это стилевое решение, которое я, конечно же, оставлю на ваше усмотрение.
как документы говорят :
Примечание :
объект
не не ] имеют__ dict __
, поэтому вы не можете назначать произвольные атрибуты экземпляру классаобъекта
.
Вы можете просто использовать экземпляр класса-пустышки.
Встроенный объект
может быть создан, но для него нельзя установить какие-либо атрибуты. (Я бы хотел, чтобы это было возможно именно для этой цели.) У него нет __ dict __
для хранения атрибутов.
Обычно я просто делаю это:
class Object(object):
pass
a = Object()
a.somefield = somevalue
По возможности я даю классу Object
более значимое имя, в зависимости от того, какие данные я в него помещаю.
Некоторые люди поступают иначе, используя подкласс dict
, который разрешает доступ к атрибутам для получения ключей. ( d.key
вместо d ['key']
)
Изменить : в качестве дополнения к вашему вопросу можно использовать setattr
. Вы просто не можете использовать setattr
в экземплярах object ()
.
params = ['attr1', 'attr2', 'attr3']
for p in params:
setattr(obj.a, p, value)
Какие предметы вы используете? Просто попробовал это с образцом класса, и он отлично работал:
class MyClass:
i = 123456
def f(self):
return "hello world"
b = MyClass()
b.c = MyClass()
setattr(b.c, 'test', 123)
b.c.test
И я получил 123
в качестве ответа.
Единственная ситуация, когда я вижу это сбой, - это когда вы пытаетесь использовать setattr
для встроенного объекта.
Обновление: из комментария это повторение: Почему вы не можете добавлять атрибуты к объекту в python?
Есть несколько способов достичь этой цели. В основном вам нужен объект, который можно расширять.
obj.a = type('Test', (object,), {})
obj.a.b = 'fun'
obj.b = lambda:None
class Test:
pass
obj.c = Test()