Как я могу создать объект и добавить атрибуты к нему?

Я хочу создать динамический объект (в другом объекте) в 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 в примере выше?

273
задан Martin Thoma 6 April 2018 в 00:54
поделиться

5 ответов

Вы можете использовать мой древний рецепт Bunch , но если вы не хотите создавать «класс связки», очень простой уже существует в Python - все функции могут иметь произвольные атрибуты (включая лямбда-функции). Итак, работает следующее:

obj = someobject
obj.a = lambda: None
setattr(obj.a, 'somefield', 'somevalue')

Будет ли потеря ясности по сравнению с почтенным рецептом Bunch в порядке, это стилевое решение, которое я, конечно же, оставлю на ваше усмотрение.

192
ответ дан 23 November 2019 в 02:12
поделиться

как документы говорят :

Примечание : объект не не ] имеют __ dict __ , поэтому вы не можете назначать произвольные атрибуты экземпляру класса объекта .

Вы можете просто использовать экземпляр класса-пустышки.

8
ответ дан 23 November 2019 в 02:12
поделиться

Встроенный объект может быть создан, но для него нельзя установить какие-либо атрибуты. (Я бы хотел, чтобы это было возможно именно для этой цели.) У него нет __ 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)
314
ответ дан 23 November 2019 в 02:12
поделиться

Какие предметы вы используете? Просто попробовал это с образцом класса, и он отлично работал:

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?

1
ответ дан 23 November 2019 в 02:12
поделиться

Есть несколько способов достичь этой цели. В основном вам нужен объект, который можно расширять.

obj.a = type('Test', (object,), {})  
obj.a.b = 'fun'  

obj.b = lambda:None

class Test:
  pass
obj.c = Test()
31
ответ дан 23 November 2019 в 02:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: