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 - [email protected]
http://mail.python.org/mailman/listinfo/tutor