Python EnThound Traits.HasTraits类作为嵌套字典?

Python EnThound Traits.HasTraits类作为嵌套字典?,python,dictionary,enthought,traits,traitsui,Python,Dictionary,Enthought,Traits,Traitsui,假设我有以下特征: 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 是否有标准方法将条作

假设我有以下特征:

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
是否有标准方法将
作为嵌套字典返回:

print bar_as_dict 
>>> {'c':7, 'foo':{'a':2, 'b':5}}
我基本上是试图提取对象上属于特定类型的所有子线程。我们的用例是,我们有深度嵌套的HasTrait对象,这些对象具有绘图特性,并且我们正在尝试动态查找特定对象上的所有绘图。我们有一个函数,可以从嵌套字典返回绘图,但是我们需要传入HasTrait对象,所以将它们格式化为嵌套字典会很好。如果有另一种方法可以动态检查HasTraits对象的堆栈并返回特定类型的所有traits,那也可以

。。。我无法直接从中看出这一点

解决方案尝试 我尝试使用
.traits()
方法,但它返回这些
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>}
但根据Pieter的建议,这是可行的:

print bar.traits()['c'].is_trait_type(Int)
>>> True
现在的问题是如何递归地执行此操作。

我在递归了一个嵌套字典而没有Trait值之后找到了它

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
通过测试,我可以选择只保留整数和/或类型为
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>}
bar=bar()
打印“仅保留整数类型”
打印展平对象(条形,整数)
打印“\n仅污染FOO对象类型”
打印展平对象(条形,Foo)
>>>仅保留整数类型
>>>{'c':7'foo.b':5'foo.a':2}
>>>仅重新绘制FOO对象类型
>>>{'foo':}

Foo表示我所追求的特殊绘图特征,因此我现在可以有效地返回它们。

我认为TreeEditor在某个时候会这样做,因为它允许您动态检查这些对象。我将继续查看编辑器源代码,试图指出这种行为。
bar.traits()['c']
是一个
CTrait
,因此它显然不是
int
。但是根据文档,
CTrait
s有一个名为
is\u trait\u type
的方法。你试过这么叫吗?我想它需要
Int
作为参数,而不是
Int
,因为它需要一个trait类型。谢谢,这很有效,让我更接近它。现在我必须尝试修改递归代码,我必须在嵌套对象上这样做。我将根据提示更新我的答案:如果存在从子级到父级的任何引用,这将导致递归错误。例如,如果嵌套对象引用回其父对象。
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>}