[Tutor] Some sample code: review?

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Thu Nov 9 19:42:09 CET 2006


Hi everyone,


I wrote up some sample code to make a more extensible str()-like function. 
I'd like some comments before putting it up onto the Python Cookbook:

#####################################################################
class DeepStr:
     """Deep stringifier."""
     def __init__(self, default_str=str,
                        recursive_str=lambda obj, dstr: "..."):
         """Creates a new DeepStr.  Once constructed, call as if this
         were a function that takes objects and returns strings.

         default_str is the default function used on types that this
         does not recognize.

         If we hit structure that's already been traversed,
         uses recursive_str to represent that structure."""
         self.__handlers = []
         self.__default_str = default_str
         self.__recursive_str = recursive_str

     def __call__(self, obj):
         """Takes a datum and returns a string of that object."""
         return self.__deepstr(obj, {})

     def __deepstr(self, obj, _seen):
         if id(obj) in _seen:
             return self.__recursive_str(obj, self)
         _seen[id(obj)] = True

         for h in self.__handlers:
             result = h(obj, lambda o: self.__deepstr(o, _seen))
             if result != None:
                 return result
         return self.__default_str(obj)

     def register(self, handler):
         """register: (object (object -> string) -> string or None)
            Registers a new handler type.  Handers take in the object
            as well as a str() function, and returns either a string
            if it can handle the object, or None otherwise.  The second
            argument should be used on substructures."""
         self.__handlers.append(handler)


def handle_list(obj, dstr):
     if isinstance(obj, list):
         return "[" + ", ".join([dstr(x) for x in obj]) + "]"
     return None

def handle_tuple(obj, dstr):
     if isinstance(obj, tuple):
         return "(" + ", ".join([dstr(x) for x in obj]) + ")"
     return None

def handle_dict(obj, dstr):
     if isinstance(obj, dict):
         return ("{" +
                 ", ".join([dstr(k) + ':' + dstr(v)
                            for (k, v) in obj.items()]) +
                 "}")
     return None

dstr = DeepStr()
dstr.register(handle_list)
dstr.register(handle_tuple)
dstr.register(handle_dict)
#####################################################################


The idea is that Python's str() on lists uses repr() on internal 
structure, which some people might consider a little wacky.  dstr(), on 
the other hand, will go all the way deeply through a structure, using the 
same stringifier.  It's also open for extension so that it can handle 
different container types in the future.

Any comments would be greatly appreciated.


More information about the Tutor mailing list