如何创建一个对象并添加属性?
我想在Python中创建一个动态对象,然后给它添加属性。但是这样做没有成功:
obj = object()
obj.somefield = "somevalue"
出现了错误:'object'对象没有'somefield'这个属性
想了解为什么这样做不行,可以查看这个链接:无法在"object"类的实例上设置属性.
18 个回答
189
在Python 3.3及以上版本中,有一个叫做 types.SimpleNamespace
的类。
obj = someobject
obj.a = SimpleNamespace()
for p in params:
setattr(obj.a, p, value)
# obj.a.attr1
如果你想创建不可变的对象,可以使用 collections.namedtuple
或者 typing.NamedTuple
。而 PEP 557 -- 数据类 则提供了一种可变的选择。
如果你需要更丰富的功能,可以 尝试一下 attrs
这个包。可以看看 这个示例。另外,pydantic
也值得一看。
468
内置的 object
是可以创建的,但不能给它设置任何属性。(我希望它可以这样做,正是为了这个目的。)这是因为它没有 __dict__
来存放属性。
我一般是这样做的:
class Object(object):
pass
obj = Object()
obj.somefield = "somevalue"
不过可以考虑给 Object
类起个更有意义的名字,这样更能反映它所包含的数据。
另一种选择是使用 dict
的子类,这样可以通过属性访问来获取键:
class AttrDict(dict):
def __getattr__(self, key):
return self[key]
def __setattr__(self, key, value):
self[key] = value
obj = AttrDict()
obj.somefield = "somevalue"
如果想用字典来创建对象属性,可以这样做:
d = {"a": 1, "b": 2, "c": 3}
for k, v in d.items():
setattr(obj, k, v)
271
你可以使用我以前的一个Bunch方法,但如果你不想自己创建一个“Bunch类”,其实Python里已经有一个非常简单的解决方案——所有的函数都可以有任意的属性(包括lambda函数)。所以,下面的代码是可以工作的:
obj = lambda: None
obj.somefield = 'somevalue'
至于和老旧的Bunch
方法相比,是否会失去一些清晰度,这个就看你自己的风格选择了。