Object trees in Python
为了访问对象,我希望在字典或类似对象上自动完成。以下是我目前拥有的:
1 2 3 4 5 | class Foo: def DoFoo(self): pass list = {"x": Foo(),"y": Foo()} |
现在我想做的是:
1 | list.x.DoFoo() |
如何用以后可以用IPython自动完成访问的对象填充列表?
我需要像我在这里看到的那样的"一流工厂"吗?
自定义类的实例可以作为您在其上设置的属性的容器。这可以简单地开始:
1 2 3 4 5 6 7 8 | class MyContainer: pass a = MyContainer() a.x = Foo() a.y = Foo() a.x.DoFoo() |
您可以使传递作为构造函数一部分的属性的能力变得更加复杂(使用与
1 2 3 4 5 6 7 | def MyContainer: def __init__(self, vals={}, **kwvals): self.__dict__.update(vals, **kwvals) a = MyContainer({"x":Foo()}, y=Foo()) # there are multiple ways to pass the args a.x.DoFoo() |
如果在创建此类容器之后不需要添加或删除值,则可以使用标准库的
1 2 3 4 5 6 7 | from collections import namedtuple A = namedtuple("A", ["x","y"]) a = A(Foo(), y=Foo()) # can use positional or keyword arguments a.x.DoFoo() # this still works! a.x ="something else" # but this will raise an error |
您需要覆盖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | class Foo(object): attr_a = 'default_attr_a_value' attr_b = 'default_attr_b_value' def __init__(self, *args, **kwargs): if len(args) >= 2: self.attr_a = args[0] self.attr_b = args[1] if len(args) == 1: self.attr_a = args[0] # holds the"emulated" attributes self._properties = kwargs def __getattr__(self, name): if name in self._properties: return self._properties[name] else: raise AttributeError def __hasattr__(self, name): return name in self._properties bar = Foo('modified_value_of_attr_a', **{'aaa':1,'bbb':2}) print bar.attr_a print bar.attr_b print bar.aaa try: print bar.sss except AttributeError: print 'Attribute error raised!' list_attrs = ['attr_a', 'aaa', 'sss'] for a in list_attrs: if hasattr(bar, a): print 'bar, instance of Foo, has an attribute named"%s"' % a else: print 'bar, instance of Foo, doesn\'t have an attribute named"%s"' % a |
多读