我想创建一个对象,然后动态为该对象添加属性。这是一些伪代码EX1:
a = object()
a.attr1 = 123
a.attr2 = '123'
a.attr3 = [1,2,3]
EX2:此 PDF 的第一页
在 Python 中,是否可以动态向对象添加属性(类似于我给出的两个示例)?如果是,如何?
我想创建一个对象,然后动态为该对象添加属性。这是一些伪代码EX1:
a = object()
a.attr1 = 123
a.attr2 = '123'
a.attr3 = [1,2,3]
EX2:此 PDF 的第一页
在 Python 中,是否可以动态向对象添加属性(类似于我给出的两个示例)?如果是,如何?
如果您使用的是 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]
在 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
不管你喜欢与否,你都在使用!
这是一个例子:
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
所以,答案是“是”。尽管这可能不是一个好主意(可能会导致诸如丢失属性等问题)。
如果你真的想为匿名类的匿名实例添加属性,你可以这样写:
>>> obj = type('obj', (), {})()
>>> obj.attr1 = 123
>>> obj.attr2 = '123'
>>> obj.attr3 = [1,2,3]
但是,真的,不要这样做!
嗯,我错过了什么吗?举个例子:
class C():
def __init__(self, x):
self.myX = x
c = C(42)
c.attr1 = 123
print c.myX
print c.attr1
似乎是什么问题?
我将字典用于您描述的确切目的(至少从我对问题的理解来看)......
dict = {}
dict["attr1"] = 123
dict["attr2"] = '123'
dict["attr3"] = [1,2,3]
dict.get("attr1")