Я хочу создать динамический объект (внутри другого объекта) в Python, а затем добавить к нему атрибуты.
Я попытался:
obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')
но это не сработало.
Любые идеи?
редактировать:
Я устанавливаю атрибуты из 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
из for
цикла.
Как бы я установить атрибут на основе значения p
в примере выше?
python
class
object
attributes
Джон
источник
источник
a = object()
и вам это нужноobj.a = object()
. Опять же, я говорю о примере: в вашем реальном коде объект внутри объекта может быть полезен.Ответы:
Вы можете использовать мой древний рецепт Bunch , но если вы не хотите создавать «класс сгустков», в Python уже существует очень простой - все функции могут иметь произвольные атрибуты (включая лямбда-функции). Итак, следующие работы:
Будет ли потеря ясности по сравнению с почтенным
Bunch
рецептом в порядке, это стильное решение, которое я, конечно, оставлю на ваше усмотрение.источник
lambda: 23
), поэтому такие эксперты используютlambda
s для этой цели. по-видимому, не чувствовал бы ничего, как "взломать". Лично мне не очень нравитсяlambda
в Python - но это вопрос личного вкуса.lambda
подходит ли шаблон для вашего варианта использования, может привести к осознанию того, что то, о чем вы изначально думали как о данных, на самом деле больше похоже на функцию - или, в любом случае, на функтор.from argparse import Namespace
хотя я бы хотел, чтобы он жил в другом месте *, например,collection
) - снова использовать уже существующий тип, просто лучший, и все же избегать создания нового типа. Но этого не было тогда :-).Встроенный
object
может быть создан, но не может иметь никаких атрибутов. (Я бы хотел, чтобы именно для этой цели.) Он не имеет__dict__
атрибутов.Я вообще просто делаю это:
Когда я могу, я даю
Object
классу более осмысленное имя, в зависимости от того, какие данные я в него помещаю.Некоторые люди делают разные вещи, когда используют подкласс,
dict
который позволяет доступ к атрибутам для доступа к ключам. (d.key
вместоd['key']
)Изменить : Для добавления к вашему вопросу, использование
setattr
в порядке. Вы просто не можете использоватьsetattr
вobject()
случаях.источник
foo = object()
работает, но вы ничего не можете с этим поделатьtype....
или лямбда никогда не было моей любимой, как текстовая рвота в моем коде. Но эта идея отлично подходит для использования объектов для хранения свойств. Делая код более читабельным b / c, когда я вижу лямбду, я замедляю чтение до 25%, в то время как ваш путь имеет смысл! Спасибо.Struct
в качестве имени класса, чтобы сделать его более очевидным. Сэкономил мне кучу печатать["
и"]
, ура!В
types.SimpleNamespace
Python 3.3+ есть класс :collections.namedtuple
,typing.NamedTuple
может быть использован для неизменных объектов. PEP 557. Классы данных предлагают изменчивую альтернативу.Для более богатой функциональности вы можете попробовать
attrs
пакет . Смотрите пример использования .источник
argparse.Namespace
классattrs
Пакет @Roel поддерживает Python 2.7Есть несколько способов достичь этой цели. В основном вам нужен объект, который можно расширять.
источник
obj.a = type('', (), {})
mock
Модуль в основном сделаны для этого.источник
unittest.Mock
является частью стандартной библиотеки начиная с Python 3.3 ( docs.python.org/3/library/unittest.mock.html )mock
в нем чего-то. Просто странно для меня.Теперь вы можете сделать (не уверен, что это тот же ответ, что и evilpie):
источник
Попробуйте код ниже:
источник
Вы также можете использовать объект класса напрямую; это создает пространство имен:
источник
как говорят документы :
Вы можете просто использовать экземпляр класса-пустышки.
источник
Эти решения очень полезны при тестировании. Основываясь на ответах всех остальных, я делаю это в Python 2.7.9 (без статического метода я получаю TypeError (метод unbound ...):
источник
Какие объекты вы используете? Просто попробовал это с примером класса, и он работал нормально:
И я получил
123
как ответ.Единственная ситуация, в которой я вижу это сбой - это если вы пытаетесь
setattr
использовать встроенный объект.Обновление: из комментария это повторение: почему вы не можете добавить атрибуты для объекта в Python?
источник
Подходя к этому в конце дня, но вот мой пенниворт с объектом, который, как оказалось, содержит некоторые полезные пути в приложении, но вы можете адаптировать его для чего угодно, где вы хотите что-то вроде информации, к которой вы можете получить доступ с помощью getattr и точечной нотации (вот о чем я думаю, этот вопрос на самом деле):
Это круто, потому что сейчас:
Таким образом, здесь используется объект функции, подобный приведенным выше ответам, но функция используется для получения значений (вы все равно можете использовать их,
(getattr, x_path, 'repository')
а неx_path('repository')
если хотите)источник
Если мы сможем определить и объединить все атрибуты и значения вместе перед созданием вложенного объекта, то мы могли бы создать новый класс, который принимает аргумент словаря при создании.
Мы также можем разрешить ключевые аргументы. Смотрите этот пост .
источник
источник
Иначе, как я вижу, вот так:
источник
class a: pass
дает всю необходимую мощность.