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