我想在Python中创建一个动态对象(在另一个对象内),然后为其添加属性 .
我试过了:
obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')
但这没用 .
有任何想法吗?
编辑:
我从 for
循环设置属性,循环遍历值列表,例如
params = ['attr1', 'attr2', 'attr3']
obj = someobject
obj.a = object()
for p in params:
obj.a.p # where p comes from for loop variable
在上面的例子中,我会得到 obj.a.attr1
, obj.a.attr2
, obj.a.attr3
.
我使用了 setattr
函数,因为我不知道如何从 for
循环中执行 obj.a.NAME
.
如何根据上面示例中的 p
的值设置属性?
16 回答
您也可以直接使用类对象;它创建一个命名空间:
这些解决方案在测试期间非常有用 . 基于其他人的答案我在Python 2.7.9中这样做(没有staticmethod我得到一个TypeError(未绑定的方法......):
你使用的是哪些物品?刚尝试使用示例类,它运行良好:
我得到了
123
作为答案 .我看到这种失败的唯一情况是你在内置对象上尝试
setattr
.更新:从评论中重复:Why can't you add attributes to object in python?
你可以使用我古老的Bunch食谱,但如果你不想制作一个"bunch class",Python中已经存在一个非常简单的 - 所有函数都可以有任意属性(包括lambda函数) . 所以,以下工作:
与古老的
Bunch
食谱相比,是否会失去清晰度是一种风格决定,我当然会留给你 .内置的
object
可以实例化,但可以__dict__
来保存属性 .我通常只是这样做:
当我可以的时候,我给
Object
类一个更有意义的名字,这取决于我放入的数据类型 .有些人做了不同的事情,他们使用
dict
的子类,允许属性访问获取键 . (d.key
而不是d['key']
)Edit :对于您的问题的补充,使用
setattr
就可以了 . 你不能在object()
实例上使用setattr
.有types.SimpleNamespace class in Python 3.3+:
collections.namedtuple,typing.NamedTuple可用于不可变对象 . PEP 557 -- Data Classes提出了一个可变的替代方案 .
要获得更丰富的功能,您可以try attrs package . 见an example usage .
有几种方法可以实现这一目标 . 基本上你需要一个可扩展的对象 .
现在你可以做(不确定它是否与evilpie一样):
mock
模块基本上是为此而制作的 .请尝试以下代码:
as docs say:
你可以使用虚拟类实例 .
在这一天晚些时候来到这里,但是我的pennyworth有一个对象恰好在应用程序中保留了一些有用的路径,但你可以调整它以适应任何你想要使用getattr和点符号访问的信息分类 . (这是我认为这个问题的真正含义):
这很酷,因为现在:
所以这就像上面的答案一样使用函数对象,但是使用函数来获取值(如果你愿意,你仍然可以使用
(getattr, x_path, 'repository')
而不是x_path('repository')
) .如果我们可以在创建嵌套对象之前确定并聚合所有属性和值,那么我们可以创建一个新的类,它在创建时接受字典参数 .
我们还可以允许关键字参数 . 见this post .
我这样看的其他方式:
这一切都在docs .
TLDR:你需要断言mock的
return_value
属性,其余的是'Magic' .例: