Reimplementing dir()

Python 2.6 introduces a special dir method for objects, which is used to override the default behaviour of dir(), which provides a list of useful attributes of an object.

Unfortunately dir() has a few special cases that probably should be handled if it's being overridden.

Here's a translation from the C source of Python's dir() builtin:

def default_dir(obj):
    d = {}

    def merge_class_dict(cls):
        if hasattr(cls, "__dict__"):
            d.update(cls.__dict__)
        for base in getattr(cls, "__bases__", []):
            merge_class_dict(base)
        return d

    if type(obj) == types.ModuleType:
        d.update(obj.__dict__)
    elif type(obj) == type or type(obj) == types.ClassType:
        merge_class_dict(obj)
    else:
        d.update( getattr(obj, "__dict__", {}) )
        d.update( (m, None) for m in getattr(obj, "__members__", []) )
        d.update( (m, None) for m in getattr(obj, "__methods__", []) )
        if hasattr(obj, "__class__"):
            merge_class_dict(obj.__class__)

    d = d.keys()
    d.sort()
    return d

This would be slightly simpler if object implemented dir, so inheritance could be used:

class DirableObject():
    def __dir__(self):
        return list(set(self.__dict__.keys() + dir(self.__class__)))

class DirableType(DirableObject):
    def __dir__(self):
        d = set(self.__dict__.keys())
        for base in self.__bases__:
            d |= dir(base)
        return list(d)

class DirableModule(DirableObject):
    def __dir__(self):
        return self.__dict__.keys()        

And, of course, that in turn is completely usable right now! Huzzah!

Powered by Sputnik | XHTML 1.1