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