How can I create an object and add attributes to it?
我想在python中创建一个动态对象(在另一个对象内部),然后向它添加属性。
我尝试过:
1 2 3 | obj = someobject obj.a = object() setattr(obj.a, 'somefield', 'somevalue') |
但这不起作用。
有什么想法吗?
编辑:
我正在设置
1 2 3 4 5 6 | params = ['attr1', 'attr2', 'attr3'] obj = someobject obj.a = object() for p in params: obj.a.p # where p comes from for loop variable |
号
在上面的例子中,我会得到
我使用了
在上面的示例中,如何根据
内置的
我通常只是这样做:
1 2 3 4 5 | class Object(object): pass a = Object() a.somefield = somevalue |
如果可以的话,我会给
有些人做的是另一件事,他们使用
编辑:对于你的问题,使用
1 2 3 | params = ['attr1', 'attr2', 'attr3'] for p in params: setattr(obj.a, p, value) |
号
您可以使用我的古老的束配方,但是如果您不想创建一个"束类",在Python中已经存在一个非常简单的类——所有函数都可以有任意的属性(包括lambda函数)。因此,以下工作:
1 2 3 | obj = someobject obj.a = lambda: None setattr(obj.a, 'somefield', 'somevalue') |
。
与古老的
python 3.3+中有
1 2 3 4 5 | obj = someobject obj.a = SimpleNamespace() for p in params: setattr(obj.a, p, value) # obj.a.attr1 |
。
为了获得更丰富的功能,您可以尝试
实现这一目标有几种方法。基本上,您需要一个可扩展的对象。
1 2 3 4 5 6 7 8 | obj.a = type('Test', (object,), {}) obj.a.b = 'fun' obj.b = lambda:None class Test: pass obj.c = Test() |
1 2 3 | import mock obj = mock.Mock() obj.a = 5 |
号
现在你可以这样做了(不确定这是否与Evilpie的答案相同):
1 2 3 | MyObject = type('MyObject', (object,), {}) obj = MyObject() obj.value = 42 |
。
请尝试以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $ python >>> class Container(object): ... pass ... >>> x = Container() >>> x.a = 10 >>> x.b = 20 >>> x.banana = 100 >>> x.a, x.b, x.banana (10, 20, 100) >>> dir(x) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'banana'] |
还可以直接使用类对象;它创建一个命名空间:
1 2 3 | class a: pass a.somefield1 = 'somevalue1' setattr(a, 'somefield2', 'somevalue2') |
号
正如医生所说:
Note:
object does not have a__dict__ , so you can’t assign arbitrary attributes to an instance of theobject class.
号
您可以使用虚拟类实例。
这些解决方案在测试期间非常有用。基于其他人的答案,我在python 2.7.9中这样做(没有staticmethod,我会得到一个typeerror(unbound method…):
1 2 3 4 | In [11]: auth = type('', (), {}) In [12]: auth.func = staticmethod(lambda i: i * 2) In [13]: auth.func(2) Out[13]: 4 |
您使用的是哪些对象?刚用一个示例类尝试过,它运行得很好:
1 2 3 4 5 6 7 8 9 | class MyClass: i = 123456 def f(self): return"hello world" b = MyClass() b.c = MyClass() setattr(b.c, 'test', 123) b.c.test |
我得到了
我看到的唯一失败的情况是,如果您在一个内置对象上尝试
更新:从注释中可以重复:为什么不能在Python中向对象添加属性?
如果我们可以在创建嵌套对象之前确定并聚合所有属性和值,那么我们可以创建一个新类,在创建时使用字典参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # 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' |
号
我们还可以允许关键字参数。看看这篇文章。
1 2 3 4 5 6 7 8 9 10 | 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') |
号
今天晚些时候来到这里,但这里是我的一本小册子,上面有一个对象刚好在应用程序中保留了一些有用的路径,但是你可以将它调整为任何你想要的信息,你可以用getattr和dot符号访问的排序口述(这就是我认为这个问题真正的目的):
1 2 3 4 5 6 7 8 | 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)) |
。
这很酷,因为现在:
1 2 3 4 5 | In [1]: x_path.projects Out[1]: '/home/x/projects' In [2]: x_path('caches') Out[2]: '/home/x/caches' |
号
因此,它使用类似上述答案的函数对象,但使用函数来获取值(如果愿意,您仍然可以使用
1 2 3 4 5 | di = {} for x in range(20): name = '_id%s' % x di[name] = type(name, (object), {}) setattr(di[name],"attr","value") |
。
我看到的另一种方式是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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) |
号