question on namedtuple

Chris Rebert clp2 at rebertia.com
Thu Apr 1 16:04:25 EDT 2010


On Thu, Apr 1, 2010 at 11:35 AM, hetchkay <hetchkay at 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



More information about the Python-list mailing list