Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > question on namedtuple

Reply
Thread Tools

question on namedtuple

 
 
hetchkay
Guest
Posts: n/a
 
      04-01-2010
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)) ].

Thanks in advance for your help.

Krishnan
 
Reply With Quote
 
 
 
 
Chris Rebert
Guest
Posts: n/a
 
      04-01-2010
On Thu, Apr 1, 2010 at 11:35 AM, hetchkay <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      04-01-2010
hetchkay wrote:

> 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)) ].


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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: collections.namedtuple: conflicting instances? Chris Rebert Python 1 09-23-2010 05:55 PM
collections.namedtuple: conflicting instances? David A. Barrett Python 0 09-23-2010 04:28 PM
namedtuple suggestions Jason R. Coombs Python 1 06-13-2008 04:17 PM
Question on Transcender Question :-) eddiec MCSE 6 05-20-2004 06:59 AM
Question re: features of the 831 router (also a 924 question) Wayne Cisco 0 03-02-2004 07:57 PM



Advertisments