8

我想创建一个对象,然后动态为该对象添加属性。这是一些伪代码EX1:

a = object()
a.attr1 = 123
a.attr2 = '123'
a.attr3 = [1,2,3]

EX2:此 PDF 的第一页

在 Python 中,是否可以动态向对象添加属性(类似于我给出的两个示例)?如果是,如何?

4

6 回答 6

7

如果您使用的是 Python 3.3+,请使用types.SimpleNamespace

>>> import types
>>> a = types.SimpleNamespace()
>>> a.attr1 = 123
>>> a.attr2 = '123'
>>> a.attr3 = [1,2,3]
>>> a.attr1
123
>>> a.attr2
'123'
>>> a.attr3
[1, 2, 3]
于 2013-08-14T14:42:29.303 回答
3

在 Python 中,是否可以动态向对象添加属性(类似于我给出的两个示例)?

是的。

如果是,如何?

你可以这样做:

class AttrHolder:
    pass

a = AttrHolder()

a.attr1 = 123
a.attr2 = '123'
a.attr3 = [1,2,3]

甚至是真正可怕的事情,例如:

import email #my choice of module is arbitrary

email.random_attribute = 'hello'

未问的问题:你应该这样做吗?可能不是。您只是将这些东西用作适当的dict. 如果您想要命名属性,请考虑使用namedtuple.

A = namedtuple('Attribute_Holder',['attr1','attr2','attr3'])
a = A(123,'123',[1,2,3])

这为 提供了一个(松散的)合同A,并给出了一个不错的repr

In [70]: print(a)
Attribute_Holder(attr1=123, attr2='123', attr3=[1, 2, 3])

或者只使用dict. 这就是他们的目的。

实际上,这就是您“动态添加属性”时所做的事情,只是使用了不必要的抽象层。考虑一下,使用上面的AttrHolder

In [77]: a = AttrHolder()

In [78]: a.__dict__
Out[78]: {}

In [79]: a.hi = 'hello'

In [80]: a.__dict__
Out[80]: {'hi': 'hello'}

dict不管你喜欢与否,你都在使用!

于 2013-08-14T14:58:18.720 回答
2

这是一个例子:

class Test:
    pass
for mark, name in enumerate(("attr1", "attr2", "attr3")):
    setattr(Test, name, mark)
print Test.attr1
print Test.attr2
print Test.attr3

输出:

0
1
2

所以,答案是“是”。尽管这可能不是一个好主意(可能会导致诸如丢失属性等问题)。

于 2013-08-14T14:43:46.327 回答
0

如果你真的想为匿名类的匿名实例添加属性,可以这样写:

>>> obj = type('obj', (), {})()
>>> obj.attr1 = 123
>>> obj.attr2 = '123'
>>> obj.attr3 = [1,2,3]

但是,真的,不要这样做!

于 2013-08-14T15:05:29.353 回答
0

嗯,我错过了什么吗?举个例子:

class C():
   def __init__(self, x):
       self.myX = x

c = C(42)
c.attr1 = 123
print c.myX
print c.attr1

似乎是什么问题?

于 2013-08-14T14:52:14.627 回答
0

我将字典用于您描述的确切目的(至少从我对问题的理解来看)......

dict = {}
dict["attr1"] = 123
dict["attr2"] = '123'
dict["attr3"] = [1,2,3]

dict.get("attr1")
于 2013-08-14T14:57:32.463 回答