Как я могу создать объект и добавить к нему атрибуты? - PullRequest
257 голосов
/ 13 мая 2010

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

Ответы [ 15 ]

1 голос
/ 13 мая 2010

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

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?

0 голосов
/ 20 ноября 2018

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

# python 2.7

class NestedObject():
    def __init__(self, initial_attrs):
        for key in initial_attrs:
            setattr(self, key, initial_attrs[key])

obj = someobject
attributes = { 'attr1': 'val1', 'attr2': 'val2', 'attr3': 'val3' }
obj.a = NestedObject(attributes)
>>> obj.a.attr1
'val1'
>>> obj.a.attr2
'val2'
>>> obj.a.attr3
'val3'

Мы также можем разрешить использование ключевых слов. Смотрите этот пост .

class NestedObject(object):
    def __init__(self, *initial_attrs, **kwargs):
        for dictionary in initial_attrs:
            for key in dictionary:
                setattr(self, key, dictionary[key])
        for key in kwargs:
            setattr(self, key, kwargs[key])


obj.a = NestedObject(attr1='val1', attr2='val2', attr3= 'val3')
0 голосов
/ 13 мая 2016

Иначе, как я вижу, вот так:

import maya.cmds

def getData(objets=None, attrs=None):
    di = {}
    for obj in objets:
        name = str(obj)
        di[name]=[]
        for at in attrs:
            di[name].append(cmds.getAttr(name+'.'+at)[0])
    return di

acns=cmds.ls('L_vest_*_',type='aimConstraint')
attrs=['offset','aimVector','upVector','worldUpVector']

getData(acns,attrs)
0 голосов
/ 02 марта 2016

Подходя к этому в конце дня, но вот мой пенниворт с объектом, который, как оказалось, содержит некоторые полезные пути в приложении, но вы можете адаптировать его для чего угодно, где вы хотите что-то вроде информации, которую вы можете получить с помощью getattr и точечные обозначения (о чем, собственно, и думается этот вопрос):

import os

def x_path(path_name):
    return getattr(x_path, path_name)

x_path.root = '/home/x'
for name in ['repository', 'caches', 'projects']:
    setattr(x_path, name, os.path.join(x_path.root, name))

Это круто, потому что сейчас:

In [1]: x_path.projects
Out[1]: '/home/x/projects'

In [2]: x_path('caches')
Out[2]: '/home/x/caches'

Таким образом, здесь используется объект функции, подобный приведенным выше ответам, но используется функция для получения значений (вы все равно можете использовать (getattr, x_path, 'repository') вместо x_path('repository'), если хотите).

0 голосов
/ 27 декабря 2013
di = {}
for x in range(20):
    name = '_id%s' % x
    di[name] = type(name, (object), {})
    setattr(di[name], "attr", "value")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...