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)) ].
Thanks in advance for your help.
Krishnan
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
I don't think there is a safe way to do this short of a comprehensive list
of namedtuple classes. In practice it may be sufficient to check the duck
type of the tuple subclass, e. g.:
elif isinstance(obj, (list, set)):
return obj.__class__(map(handleObj, obj))
elif isinstance(obj, tuple):
try:
make = obj._make
except AttributeError:
make = obj.__class__
return make(handleObj(item) for item in obj)
Peter