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.
_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to