首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Python中创建新的未知或动态/扩展对象

如何在Python中创建新的未知或动态/扩展对象
EN

Stack Overflow用户
提问于 2012-12-24 07:41:47
回答 7查看 33.8K关注 0票数 41

在python中,我们如何在没有预定义类的情况下创建一个新对象,并在以后动态地向其添加属性?

示例:

代码语言:javascript
复制
dynamic_object = Dynamic()
dynamic_object.dynamic_property_a = "abc"
dynamic_object.dynamic_property_b = "abcdefg"

做这件事最好的方法是什么?

编辑,因为很多人在评论中建议我可能不需要这个。

问题是我有一个序列化对象属性的函数。出于这个原因,由于一些构造函数的限制,我不想创建一个预期类的对象,而是创建一个类似的对象,比如说模拟,添加我需要的任何“自定义”属性,然后将其反馈给函数。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-12-24 07:44:46

只需定义您自己的类即可:

代码语言:javascript
复制
class Expando(object):
    pass

ex = Expando()
ex.foo = 17
ex.bar = "Hello"
票数 46
EN

Stack Overflow用户

发布于 2012-12-24 09:46:45

仅仅使用对象来保存值并不是最具Pythonic风格的编程方式。这在没有良好关联容器的编程语言中很常见,但在Python中,您可以使用use a dictionary:

代码语言:javascript
复制
my_dict = {} # empty dict instance

my_dict["foo"] = "bar"
my_dict["num"] = 42

您还可以使用“字典文字”一次性定义字典的所有内容:

代码语言:javascript
复制
my_dict = {"foo":"bar", "num":42}

或者,如果您的键都是合法标识符(如果您计划将它们作为属性名,它们将是合法标识符),您可以使用带有关键字参数的dict构造函数作为键-值对:

代码语言:javascript
复制
my_dict = dict(foo="bar", num=42) # note, no quotation marks needed around keys

填充字典实际上是Python在使用对象时在幕后所做的事情,例如在Ned Batchelder的答案中。他的ex对象的属性存储在字典ex.__dict__中,最终应该等于直接创建的等效dict

除非属性语法(例如ex.foo)是绝对必要的,否则您也可以完全跳过对象,直接使用字典。

票数 21
EN

Stack Overflow用户

发布于 2017-04-10 23:38:39

如果你从@Martijn的答案中采用元类化的方法,@Ned的答案可以重写得更短(尽管它显然可读性较差,但做的事情是一样的)。

代码语言:javascript
复制
obj = type('Expando', (object,), {})()
obj.foo = 71
obj.bar = 'World'

或者只是使用dict参数执行与上面相同的操作:

代码语言:javascript
复制
obj = type('Expando', (object,), {'foo': 71, 'bar': 'World'})()

对于Python3,不需要将object传递给bases参数(请参阅type 文档)。

但对于简单的情况,实例化没有任何好处,所以这样做是可以的:

代码语言:javascript
复制
ns = type('Expando', (object,), {'foo': 71, 'bar': 'World'})

同时,就我个人而言,我更喜欢用于ad-hoc测试配置案例的普通类(即没有实例化),因为它是最简单和可读的:

代码语言:javascript
复制
class ns:
    foo = 71
    bar = 'World'

更新

在Python 3.3+中,就有OP所要求的types.SimpleNamespace。它只是:

一个简单的object子类,它提供对其名称空间的属性访问,以及一个有意义的repr。

object不同,使用SimpleNamespace可以添加和删除属性。如果使用关键字参数初始化SimpleNamespace对象,则这些参数将直接添加到基础命名空间中。

代码语言:javascript
复制
import types
obj = types.SimpleNamespace()
obj.a = 123
print(obj.a) # 123
print(repr(obj)) # namespace(a=123)

然而,在Python2和Python3的stdlib中都有argparse.Namespace,它具有相同的用途:

用于存储属性的

简单对象。

通过属性名称和值实现相等,并提供简单的字符串表示形式。

代码语言:javascript
复制
import argparse
obj = argparse.Namespace()
obj.a = 123
print(obj.a) # 123 
print(repr(obj)) # Namespace(a=123)

请注意,两者都可以使用关键字参数进行初始化:

代码语言:javascript
复制
types.SimpleNamespace(a = 'foo',b = 123)
argparse.Namespace(a = 'foo',b = 123)
票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14015592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档