Enthought Traits.HasTraits class 作为嵌套字典?
Enthought Traits.HasTraits class as a nested dictionary?
假设我有以下 Traits 对象:
from traits.api import Int, HasTraits, Instance
class Foo(HasTraits):
a = Int(2)
b = Int(5)
class Bar(HasTraits):
c = Int(7)
foo = Instance(Foo,())
Bar
将允许我通过以下方式访问 Foo
上的属性 a
:
bar = Bar()
bar.foo.a
>>> 2
是否有一种标准方法可以将 return bar
作为以下形式的嵌套字典:
print bar_as_dict
>>> {'c':7, 'foo':{'a':2, 'b':5}}
我实际上是在尝试提取特定类型对象的所有子特征。我们的用例是我们拥有具有绘图特征的深层嵌套 HasTrait 对象,并且我们正在尝试动态查找特定对象上的所有绘图。我们有一个函数可以 return 嵌套字典中的图,但我们需要将 HasTrait 对象传入,因此将它们格式化为嵌套字典会很棒。如果有另一种方法可以动态检查 HasTraits 对象的堆栈和 return 特定类型的所有特征,那也可以。
Here's a link to the HasTraits API...无法直接从中得出结论。
解决方案尝试
我试过使用 .traits()
方法,但它 return 是这些 CTrait
对象。
print bar.traits()
>>>{'trait_added': <traits.traits.CTrait object at 0x8b7439c>,
'c': <traits.traits.CTrait object at 0x8b29e9c>,
'foo': <traits.traits.CTrait object at 0x8b29e44>,
'trait_modified': <traits.traits.CTrait object at 0x8b74344>}
未按我的预期进行评估:
isinstance(bar.traits()['c'], int)
>>> False
但在 Pieter 的建议下,这行得通:
print bar.traits()['c'].is_trait_type(Int)
>>> True
现在的问题是如何递归执行此操作。
我在 递归嵌套字典 没有 特征值
之后弄明白了
def flatten_traitobject(traitobject, *types):
node_map = {}
node_path = []
def nodeRecursiveMap(traitobject, node_path):
for key in traitobject.editable_traits():
val = traitobject.get(key)[key]
for type in types:
if isinstance(val, types[0]):
node_map['.'.join(node_path + [key])] = val
try:
nodeRecursiveMap(val, node_path + [key])
except (AttributeError, TypeError):
pass
nodeRecursiveMap(traitobject, node_path)
return node_map
测试了一下,我可以选择只保留整数 and/or 只保留 Foo
类型的对象
bar=Bar()
print 'RETAINING ONLY INTEGER TYPES'
print flatten_traitobject(bar, int)
print '\nRETAINTING ONLY FOO OBJECT TYPES'
print flatten_traitobject(bar, Foo)
>>> RETAINING ONLY INTEGER TYPES
>>> {'c': 7, 'foo.b': 5, 'foo.a': 2}
>>> RETAINTING ONLY FOO OBJECT TYPES
>>> {'foo': <__main__.Foo object at 0x8f9308c>}
Foo 代表我所追求的特殊绘图特征,所以我现在可以有效地 return 它们。
假设我有以下 Traits 对象:
from traits.api import Int, HasTraits, Instance
class Foo(HasTraits):
a = Int(2)
b = Int(5)
class Bar(HasTraits):
c = Int(7)
foo = Instance(Foo,())
Bar
将允许我通过以下方式访问 Foo
上的属性 a
:
bar = Bar()
bar.foo.a
>>> 2
是否有一种标准方法可以将 return bar
作为以下形式的嵌套字典:
print bar_as_dict
>>> {'c':7, 'foo':{'a':2, 'b':5}}
我实际上是在尝试提取特定类型对象的所有子特征。我们的用例是我们拥有具有绘图特征的深层嵌套 HasTrait 对象,并且我们正在尝试动态查找特定对象上的所有绘图。我们有一个函数可以 return 嵌套字典中的图,但我们需要将 HasTrait 对象传入,因此将它们格式化为嵌套字典会很棒。如果有另一种方法可以动态检查 HasTraits 对象的堆栈和 return 特定类型的所有特征,那也可以。
Here's a link to the HasTraits API...无法直接从中得出结论。
解决方案尝试
我试过使用 .traits()
方法,但它 return 是这些 CTrait
对象。
print bar.traits()
>>>{'trait_added': <traits.traits.CTrait object at 0x8b7439c>,
'c': <traits.traits.CTrait object at 0x8b29e9c>,
'foo': <traits.traits.CTrait object at 0x8b29e44>,
'trait_modified': <traits.traits.CTrait object at 0x8b74344>}
未按我的预期进行评估:
isinstance(bar.traits()['c'], int)
>>> False
但在 Pieter 的建议下,这行得通:
print bar.traits()['c'].is_trait_type(Int)
>>> True
现在的问题是如何递归执行此操作。
我在
def flatten_traitobject(traitobject, *types):
node_map = {}
node_path = []
def nodeRecursiveMap(traitobject, node_path):
for key in traitobject.editable_traits():
val = traitobject.get(key)[key]
for type in types:
if isinstance(val, types[0]):
node_map['.'.join(node_path + [key])] = val
try:
nodeRecursiveMap(val, node_path + [key])
except (AttributeError, TypeError):
pass
nodeRecursiveMap(traitobject, node_path)
return node_map
测试了一下,我可以选择只保留整数 and/or 只保留 Foo
bar=Bar()
print 'RETAINING ONLY INTEGER TYPES'
print flatten_traitobject(bar, int)
print '\nRETAINTING ONLY FOO OBJECT TYPES'
print flatten_traitobject(bar, Foo)
>>> RETAINING ONLY INTEGER TYPES
>>> {'c': 7, 'foo.b': 5, 'foo.a': 2}
>>> RETAINTING ONLY FOO OBJECT TYPES
>>> {'foo': <__main__.Foo object at 0x8f9308c>}
Foo 代表我所追求的特殊绘图特征,所以我现在可以有效地 return 它们。