collections.namedtuple: conflicting instances?

nn pruebauno at latinmail.com
Thu Sep 23 13:55:36 EDT 2010


On Sep 23, 1:40 pm, Chris Rebert <creb... at ucsd.edu> wrote:
> On Thu, Sep 23, 2010 at 9:28 AM, David A. Barrett <c_bar... at qualcomm.com> wrote:
>
>
>
> >  I've noticed that it's possible to create conflicting instances of the
> > collections.namedtuple class:
>
> >  from collections  import namedtuple as nt
> >  IX = nt('X', 'a b')
> >  IY = nt('Y', 'c d')
> >  x = IX(0, 1)
> >  y = IY(2, 3)
>
> > The above are non-conflicting class instances and of two distinct namedtuple
> > classes and distinct instances of those classes, but what happens with this?
>
> >  IX2 = nt('X', 'g')
> >  z = IX2(10)
>
> > It looks like IX and IX2 are two distinct classes, which makes sense, but
> > what is the classname parameter passed to the constructor used for?
>
> Documentation for human readers (the .__name__ class attribute). As
> your example shows, the name you pass in doesn't have to match the
> name you assign the resulting class to and actually use (i.e. "X" vs.
> "IX"); it's rather like how you were able to use "nt" instead of
> "namedtuple".
>
> > Is it
> > an error to construct two distinct classes with the same value?
>
> Of course not. Otherwise, classes would have to have *globally unique*
> names, and stuff like the following wouldn't be possible (which would
> be bad):
>
> # mechanical.py
> class Engineer(object):
>     '''Models a mechanical engineer.'''
>     # ...
>
> # trains.py
> class Engineer(object):
>     '''Models a person who drives a train.'''
>     # ...
>
> # main.py
> # Models a train company and associated repair yard.
> import mechanical
> import trains
> # ...
>
> > Should
> > inconsistant constructions with the same name raise and exception?
>
> Probably not (see answer to previous sentence); showing a warning
> /might/ be appropriate.
>
> Cheers,
> Chris
> --http://blog.rebertia.com

This parallels another wrinkle:

>>> A=type('X',(),{'a':''})
>>> B=type('X',(),{'z':''})
>>> A
<class '__main__.X'>
>>> B
<class '__main__.X'>
>>> i=A()
>>> j=B()
>>> i
<__main__.X object at 0x013A63F0>
>>> j
<__main__.X object at 0x013A6ED0>
>>> dir(i)
['__class__', '__delattr__', '__dict__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a']
>>> dir(j)
['__class__', '__delattr__', '__dict__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'z']
>>>

The first parameter to type and namedtuple looks redundant to me.

class A: pass

should be the equivalent to

A=type((),{})

my guess is that it has to do with Python's internals: the function
probably has no way to know what variable name it is being assigned to
and anonymous classes are not wanted.



More information about the Python-list mailing list