15

I've been using the following in my code:

class Structure(dict,object):
""" A 'fancy' dictionary that provides 'MatLab' structure-like
referencing. 

"""
def __getattr__(self, attr):
    # Fake a __getstate__ method that returns None
    if attr == "__getstate__":
        return lambda: None
    return self[attr]

def __setattr__(self, attr, value):
    self[attr] = value

def set_with_dict(self, D):
    """ set attributes with a dict """
    for k in D.keys():
        self.__setattr__(k, D[k])

All in all it works for my purposes, but I've noticed that only way tab completion works is for methods in another custom class that inherited from Structure, and not for attributes. I also did this test, and I find the result a little strange:

In [2]: d = Structure()
In [3]: d.this = 'that'
In [4]: d.this
Out[4]: 'that'
In [5]: d.th<tab>
NOTHING HAPPENS

In [6]: class T():
   ...:     pass
   ...: 

In [7]: t = T()
In [8]: t.this = 'cheese'
In [9]: t.th<tab>
COMPLETES TO t.this
Out[9]: 'cheese'

What would I need to add to my class to get the tab completion to work for the attributes?

John
  • 1,263
  • 2
  • 15
  • 26
  • If you want dot access *instead of* bracket indexing, not *in addition* to it, you could just use an empty subclass of `object`. Python objects are "open" by default. `x.set_with_dict()` can be replaced with `x.__dict__.update()` – millimoose Dec 14 '12 at 00:23
  • Also, inheriting from both `dict` and `object` is redundant, since `dict` (and most standard library classes) are new-style classes and already inherit from `object`. – millimoose Dec 14 '12 at 00:26
  • Good point about the multiple inheritance. However, I do want to have _both_ bracket and dot access to my keys. I'm trying to switch my code over to using a pure python dict, but still have quite some places that rely on the dot access... – John Dec 20 '12 at 17:56

1 Answers1

23

Add this method:

def __dir__(self):
    return self.keys()

See here: http://ipython.org/ipython-doc/dev/config/integrating.html

And here: http://docs.python.org/2/library/functions.html

goodside
  • 4,429
  • 2
  • 22
  • 32
  • Thanks goodside! I missed that piece of information (not sure how) in my prior searches! – John Dec 20 '12 at 17:55
  • 1
    In the newer IPython, the tab completion windows seems to have some max number of entries with scrolling. Anyone know how to adjust that? – mathtick Mar 12 '17 at 18:37