On Thu, Apr 1, 2010 at 11:35 AM, hetchkay <hetch...@gmail.com> wrote: > Hi, > For purposes I don't want to go into here, I have the following code: > def handleObj(obj): > if isinstance(obj, MyType): > return obj.handle() > elif isinstance(obj, (list, tuple, set)): > return obj.__class__(map (handleObj, obj)) > elif isinstance(obj, dict): > return obj.__class__((handleObj(k), handleObj(v)) for k, v in > obj.items()) > else: > return obj > > This works fine except if obj is a namedtuple. A namedtuple object has > different constructor signature from tuple: >>>> tuple([1,2]) > (1,2) >>>> collections.namedtuple("sample", "a, b")([1, 2]) > Traceback (most recent call last): > File "CommandConsole", line 1, in <module> > TypeError: __new__() takes exactly 3 arguments (2 given) >>>> collections.namedtuple("sample", "a, b")(1, 2) > sample(a=1, b=2) > > Is there any easy way of knowing that the obj is a namedtuple and not > a plain tuple [so that I could use obj.__class__(*map(handleObj, obj)) > instead of obj.__class__(map(handleObj, obj)) ].
It's very slightly brittle, but a good heuristic is probably: if isinstance(obj, tuple) and all(hasattr(obj, attr_name) for \ attr_name in ('_make','_fields','_replace','_asdict')): return obj.__class__(*map(handleObj, obj)) I couldn't find/think of a more direct/reliable method. Though perhaps there's some more obscure but accurate method. Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list