Printing all the attributes in a class
请不要问我是如何陷入这种情况的。假设我有一个叫做
此类在运行时具有以下属性:
1 2 3 4 5 6 | ccollection.a.b.x = 1 ccollection.a.b.y = 3 ccollection.a.b.z = 4 ... ccollection.a.c = 3 ccollection.b = 3 |
这个类将按照上面的描述动态设置。因此,在手之前无法知道类中的属性。
现在我想打印这个类中的所有属性,例如:
1 2 3 | ccollection.a.b.x = 1 ccollection.a.b.y = 3 ccollection.a.b.z = 4 |
和
1 2 3 4 | ccollection.a.b.x = 1 ccollection.a.b.y = 3 ccollection.a.b.z = 4 ccollection.a.c = 3 |
我想你明白了。每次打印都应该在同一级别和更低级别上开始打印所有元素。我正在寻找一种递归遍历所有属性的方法(这是一种类似树的数据结构)
型
这种情况真的需要重构。您使用的对象不是设计为容器的。相反,使用容器,如dict或继承自dict的类。
如果您必须使用当前设置,我同意blckknght的观点,即最有希望的方法似乎是使用dir。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class CCollection(object): def get_children_strings(self): list_of_strings = [] for attr_name in dir(self): if attr_name not in dir(CCollection()): attr = getattr(self, attr_name) if hasattr(attr, 'get_children_strings'): list_of_strings.extend(["." + attr_name + child_string for child_string in attr.get_children_strings()]) else: list_of_strings.append("." + attr_name +" =" + str(attr)) return list_of_strings def print_tree(self, prefix): print [prefix + s for s in self.get_children_strings()] |
号
那么你可以
1 2 3 4 5 6 7 8 9 10 11 | m = CCollection() m.a = CCollection() m.a.b = CCollection() m.a.b.x = 1 m.a.b.y = 2 m.a.c = 3 m.d = 4 m.print_tree("m") m.a.print_tree("m.a") m.a.b.print_tree("m.a.b") |
并得到输出:
1 2 3 4 5 6 | >>> m.print_tree("m") ['m.a.b.x = 1', 'm.a.b.y = 2', 'm.a.c = 3', 'm.d = 4'] >>> m.a.print_tree("m.a") ['m.a.b.x = 1', 'm.a.b.y = 2', 'm.a.c = 3'] >>> m.a.b.print_tree("m.a.b") ['m.a.b.x = 1', 'm.a.b.y = 2'] |
。
为了更进一步,您可能需要使用一个带有树遍历函数的类。如果您有获取父节点的函数、无循环的保证以及保存节点名称的类变量,则可以自动生成当前通过
型
看起来您需要一个具有属性访问权限的树型结构。这可以通过子类化
此外,可以使用覆盖
编辑:
为了快速描述这一点,我希望它看起来像这样。
1 2 3 4 5 6 7 8 9 10 | class DictTree( object ): _children = {} def __getattr__( self, name ): if not name in self._children: self._children[name] = DictTree() return self._children[name] def __setattr__( self, name, v ): self._children[name] = v |
上面的工作提供了您想要的访问和API接口,但是在打印它时,我得到了一个