3

想象一下,我有以下 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,())

Bara将让我通过以下方式访问属性Foo

bar = Bar()
bar.foo.a
>>> 2

是否有一种标准方法可以bar作为嵌套字典返回:

print bar_as_dict 
>>> {'c':7, 'foo':{'a':2, 'b':5}}

我本质上是在尝试提取特定类型对象的所有子特征。我们的用例是我们有深度嵌套的具有绘图特征的 HasTrait 对象,并且我们正在尝试动态查找特定对象上的所有绘图。我们有一个函数可以从嵌套字典中返回绘图,但我们需要传入 HasTrait 对象,因此将它们格式化为嵌套字典会很棒。如果有另一种方法可以动态检查 HasTraits 对象的堆栈并返回某种类型的所有特征,那也可以。

这是 HasTraits API 的链接......无法直接从中弄清楚。

解决方案尝试

我试过使用该.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>}

没有像我预期的那样评估:

isinstance(bar.traits()['c'], int)
>>> False

但在彼得的建议之后,这行得通:

print bar.traits()['c'].is_trait_type(Int)
>>> True

现在的问题是如何递归地做到这一点。

4

1 回答 1

1

在遵循关于没有特征值的嵌套字典的递归的类似问题后,我想通了

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>}

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

于 2015-01-26T05:56:50.937 回答