我想在Python中创建一个动态对象(在另一个对象内部),然后向其添加属性。

我试着:

obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')

但这并不奏效。

什么好主意吗?

编辑:

我设置的属性从一个循环通过一个值的列表,例如。

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函数,因为我不知道如何从for循环中执行obj.a.NAME。

如何根据上面例子中的p值设置属性?


有关为什么它不起作用的详细信息,请参见不能在“object”类的实例上设置属性。


当前回答

这很好:

    exec("obj.a."+p)

如果你想将属性设置为某个值,可以这样做:

    exec("obj.a."+p+"=(the value here)")

如果值是字符串,则必须使用这些\"而不是引号,除非将值存储在变量中。

其他回答

内置对象可以被实例化,但不能在其上设置任何属性。(为了这个目的,我希望它可以。)它没有__dict__来保存属性。

我通常是这样做的:

class Object(object):
    pass

a = Object()
a.somefield = somevalue

当我可以时,我给Object类起一个更有意义的名字,这取决于我在其中放入什么样的数据。

有些人做了不同的事情,他们使用dict的子类,允许属性访问来获得键。(d.key而不是d['key'])

编辑:对于您的问题,使用setattr是很好的。你不能在object()实例上使用setattr。

params = ['attr1', 'attr2', 'attr3']
for p in params:
    setattr(obj.a, p, value)

这很好:

    exec("obj.a."+p)

如果你想将属性设置为某个值,可以这样做:

    exec("obj.a."+p+"=(the value here)")

如果值是字符串,则必须使用这些\"而不是引号,除非将值存储在变量中。

正如医生所说:

注意:object没有__dict__对象,因此不能将任意属性赋给object类的实例。

你可以使用伪类实例。

今天晚了,但这是我的一文不值的一个对象,恰好在应用程序中保存了一些有用的路径,但你可以将它用于任何你想要的信息字典,你可以通过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'),如果你喜欢的话)。

现在你可以这样做(不确定这是否与evilpie的答案相同):

MyObject = type('MyObject', (object,), {})
obj = MyObject()
obj.value = 42