如何创建一个对象并添加属性?

437 投票
18 回答
571523 浏览
提问于 2025-04-15 22:40

我想在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方法相比,是否会失去一些清晰度,这个就看你自己的风格选择了。

撰写回答