在python中,我们如何在没有预定义类的情况下创建一个新对象,并在以后动态地向其添加属性?
示例:
dynamic_object = Dynamic()
dynamic_object.dynamic_property_a = "abc"
dynamic_object.dynamic_property_b = "abcdefg"
做这件事最好的方法是什么?
编辑,因为很多人在评论中建议我可能不需要这个。
问题是我有一个序列化对象属性的函数。出于这个原因,由于一些构造函数的限制,我不想创建一个预期类的对象,而是创建一个类似的对象,比如说模拟,添加我需要的任何“自定义”属性,然后将其反馈给函数。
发布于 2012-12-24 07:44:46
只需定义您自己的类即可:
class Expando(object):
pass
ex = Expando()
ex.foo = 17
ex.bar = "Hello"
发布于 2012-12-24 09:46:45
仅仅使用对象来保存值并不是最具Pythonic风格的编程方式。这在没有良好关联容器的编程语言中很常见,但在Python中,您可以使用use a dictionary:
my_dict = {} # empty dict instance
my_dict["foo"] = "bar"
my_dict["num"] = 42
您还可以使用“字典文字”一次性定义字典的所有内容:
my_dict = {"foo":"bar", "num":42}
或者,如果您的键都是合法标识符(如果您计划将它们作为属性名,它们将是合法标识符),您可以使用带有关键字参数的dict
构造函数作为键-值对:
my_dict = dict(foo="bar", num=42) # note, no quotation marks needed around keys
填充字典实际上是Python在使用对象时在幕后所做的事情,例如在Ned Batchelder的答案中。他的ex
对象的属性存储在字典ex.__dict__
中,最终应该等于直接创建的等效dict
。
除非属性语法(例如ex.foo
)是绝对必要的,否则您也可以完全跳过对象,直接使用字典。
发布于 2017-04-10 23:38:39
如果你从@Martijn的答案中采用元类化的方法,@Ned的答案可以重写得更短(尽管它显然可读性较差,但做的事情是一样的)。
obj = type('Expando', (object,), {})()
obj.foo = 71
obj.bar = 'World'
或者只是使用dict
参数执行与上面相同的操作:
obj = type('Expando', (object,), {'foo': 71, 'bar': 'World'})()
对于Python3,不需要将object传递给bases
参数(请参阅type
文档)。
但对于简单的情况,实例化没有任何好处,所以这样做是可以的:
ns = type('Expando', (object,), {'foo': 71, 'bar': 'World'})
同时,就我个人而言,我更喜欢用于ad-hoc测试配置案例的普通类(即没有实例化),因为它是最简单和可读的:
class ns:
foo = 71
bar = 'World'
更新
在Python 3.3+中,就有OP所要求的types.SimpleNamespace
。它只是:
一个简单的
object
子类,它提供对其名称空间的属性访问,以及一个有意义的repr。
与object
不同,使用SimpleNamespace
可以添加和删除属性。如果使用关键字参数初始化SimpleNamespace
对象,则这些参数将直接添加到基础命名空间中。
import types
obj = types.SimpleNamespace()
obj.a = 123
print(obj.a) # 123
print(repr(obj)) # namespace(a=123)
然而,在Python2和Python3的stdlib中都有argparse.Namespace
,它具有相同的用途:
用于存储属性的
简单对象。
通过属性名称和值实现相等,并提供简单的字符串表示形式。
import argparse
obj = argparse.Namespace()
obj.a = 123
print(obj.a) # 123
print(repr(obj)) # Namespace(a=123)
请注意,两者都可以使用关键字参数进行初始化:
types.SimpleNamespace(a = 'foo',b = 123)
argparse.Namespace(a = 'foo',b = 123)
https://stackoverflow.com/questions/14015592
复制相似问题