Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #5230 > unrolled thread

list equal to subclass of list?

Started byRoy Smith <roy@panix.com>
First post2011-05-12 08:23 -0400
Last post2011-05-12 14:48 -0700
Articles 9 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  list equal to subclass of list? Roy Smith <roy@panix.com> - 2011-05-12 08:23 -0400
    Re: list equal to subclass of list? Ethan Furman <ethan@stoneleaf.us> - 2011-05-12 09:43 -0700
      Re: list equal to subclass of list? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-05-13 00:18 +0000
        Re: list equal to subclass of list? Ethan Furman <ethan@stoneleaf.us> - 2011-05-12 18:04 -0700
      Re: list equal to subclass of list? Roy Smith <roy@panix.com> - 2011-05-12 21:53 -0400
    Re: list equal to subclass of list? Ethan Furman <ethan@stoneleaf.us> - 2011-05-12 11:29 -0700
      Re: list equal to subclass of list? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-05-12 22:40 +0200
      Re: list equal to subclass of list? Roy Smith <roy@panix.com> - 2011-05-12 13:49 -0700
        Re: list equal to subclass of list? Ethan Furman <ethan@stoneleaf.us> - 2011-05-12 14:48 -0700

#5230 — list equal to subclass of list?

FromRoy Smith <roy@panix.com>
Date2011-05-12 08:23 -0400
Subjectlist equal to subclass of list?
Message-ID<roy-B4A109.08230412052011@news.panix.com>
I have a vague feeling this may have been discussed a long time ago, but 
I can't find the thread, so I'll bring it up again.

I recently observed in the "checking if a list is empty" thread that a 
list and a subclass of list can compare equal:

----------------------------
class MyList(list):
    "I'm a subclass"

l1 = []
l2 = MyList()

print type(l1), type(l2)
print type(l1) == type(l2)
print l1 == l2
----------------------------

when run, prints:

<type 'list'> <class '__main__.MyList'>
False
True

The docs say:

[http://docs.python.org/library/stdtypes.html]
Objects of different types, except different numeric types and different 
string types, never compare equal

[http://docs.python.org/release/2.7/reference/expressions.html#notin]
objects of different types (emphasis)always compare unequal

In the test code above, l1 an l2 are different types, at least in the 
sense that type() returns something different for each of them.  What's 
the intended behavior here?  Either the code is wrong or the docs are 
wrong.

[toc] | [next] | [standalone]


#5246

FromEthan Furman <ethan@stoneleaf.us>
Date2011-05-12 09:43 -0700
Message-ID<mailman.1479.1305217887.9059.python-list@python.org>
In reply to#5230
Roy Smith wrote:
> I recently observed in the "checking if a list is empty" thread that a 
> list and a subclass of list can compare equal:
> 
> ----------------------------
> class MyList(list):
>     "I'm a subclass"
> 
> l1 = []
> l2 = MyList()
> 
> print type(l1), type(l2)
> print type(l1) == type(l2)
> print l1 == l2
> ----------------------------
> 
> when run, prints:
> 
> <type 'list'> <class '__main__.MyList'>
> False
> True
> 
> The docs say:
> 
> [http://docs.python.org/library/stdtypes.html]
> Objects of different types, except different numeric types and different 
> string types, never compare equal

This part of the documentation is talking about built-in types, which 
your MyList is not.


> [http://docs.python.org/release/2.7/reference/expressions.html#notin]
> objects of different types *always* compare unequal

Should probably have the word 'built-in' precede 'types' here, since 
constructed objects can do whatever they have been told to do.

> In the test code above, l1 an l2 are different types, at least in the 
> sense that type() returns something different for each of them.

--> MyList.__mro__
(<class '__main__.MyList'>, <type 'list'>, <type 'object'>)

MyList is a list -- just a more specific kind of list -- as can be seen 
from its mro; this is analogous to a square (2 sets of parallel lines 
joined at 90 degree angles, both sets being the same length) also being 
a rectangle (2 sets of parallel lines joined at 90 degree angles).

> What's the intended behavior here?  Either the code is wrong or the docs
 > are wrong.

The code is correct.

~Ethan~

PS
Yes, I know my square/rectangle definitions are incomplete, thanks.  ;)

[toc] | [prev] | [next] | [standalone]


#5273

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-05-13 00:18 +0000
Message-ID<4dcc78b8$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#5246
On Thu, 12 May 2011 09:43:23 -0700, Ethan Furman wrote:

> MyList is a list -- just a more specific kind of list -- as can be seen
> from its mro; this is analogous to a square (2 sets of parallel lines
> joined at 90 degree angles, both sets being the same length) also being
> a rectangle (2 sets of parallel lines joined at 90 degree angles).

Possibly the worst analogy ever! *wink*

http://en.wikipedia.org/wiki/Circle-ellipse_problem

Also known as the square-rectangle problem.

A better analogy might be, Lassie is a dog, and Flipper is a dolphin, so 
they are different types of animal. But both dogs and dolphins are 
mammals, so in that sense, Lassie and Flipper are both mammals and 
therefore the same type of animal. It depends on what you mean by "type".



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#5275

FromEthan Furman <ethan@stoneleaf.us>
Date2011-05-12 18:04 -0700
Message-ID<mailman.1503.1305247943.9059.python-list@python.org>
In reply to#5273
Steven D'Aprano wrote:
> On Thu, 12 May 2011 09:43:23 -0700, Ethan Furman wrote:
> 
>> MyList is a list -- just a more specific kind of list -- as can be seen
>> from its mro; this is analogous to a square (2 sets of parallel lines
>> joined at 90 degree angles, both sets being the same length) also being
>> a rectangle (2 sets of parallel lines joined at 90 degree angles).
> 
> Possibly the worst analogy ever! *wink*
> 
> http://en.wikipedia.org/wiki/Circle-ellipse_problem
> 
> Also known as the square-rectangle problem.
> 
> A better analogy might be, Lassie is a dog, and Flipper is a dolphin, so 
> they are different types of animal. But both dogs and dolphins are 
> mammals, so in that sense, Lassie and Flipper are both mammals and 
> therefore the same type of animal. It depends on what you mean by "type".

I thought about using the mammal analogy instead, but geometry seemed 
simpler.  *sigh*  Oh, well, can't win 'em all!

~Ethan~

[toc] | [prev] | [next] | [standalone]


#5277

FromRoy Smith <roy@panix.com>
Date2011-05-12 21:53 -0400
Message-ID<roy-9BFE09.21530512052011@news.panix.com>
In reply to#5246
In article <mailman.1479.1305217887.9059.python-list@python.org>,
 Ethan Furman <ethan@stoneleaf.us> wrote:

> > [http://docs.python.org/library/stdtypes.html]
> > Objects of different types, except different numeric types and different 
> > string types, never compare equal
> 
> This part of the documentation is talking about built-in types, which 
> your MyList is not.
> 
> 
> > [http://docs.python.org/release/2.7/reference/expressions.html#notin]
> > objects of different types *always* compare unequal
> 
> Should probably have the word 'built-in' precede 'types' here, since 
> constructed objects can do whatever they have been told to do.

Changing the docs (in numerous places) to make it clear that this is 
only true of built-in types would indeed resolve the problem.  As it 
reads now, it's a general statement about ALL types, built-in or 
user-defined.

[toc] | [prev] | [next] | [standalone]


#5249

FromEthan Furman <ethan@stoneleaf.us>
Date2011-05-12 11:29 -0700
Message-ID<mailman.1481.1305224275.9059.python-list@python.org>
In reply to#5230
Roy Smith wrote:
> On May 12, 2011, at 11:30 AM, Eric Snow wrote:
>>
>> That definitely makes it unclear.
> 
> I don't think it's unclear at all.  It's very clear.  Clearly wrong :-)

While it is wrong (it should have 'built-in' precede the word 'types'), 
it is not wrong in the way you think -- a subclass *is* a type of its 
superclass.


>> A little further down it says that you can customize comparison with 
>> the __cmp__ special method. 
 >
> I read that as saying that if you implement __eq__(), you must make sure 
> that it returns False if self and other have different types (and 
> likewise, __ne__() should return True for that case).

Your understanding is flawed.  If your object does not know how to 
compare itself to some other object, it should return NotImplemented -- 
at that point Python will follow the rules outlined in the docs.  By 
returning NotImplemented you are allowing the other object a chance to 
perform the comparison -- after all, it might know how!  :)  If the 
other object also returns NotImplemented then (drum-roll please) they 
won't compare equal.


> The same way that it says that obj1.__lt__(obj2) must return a consistent
 > result for all types of obj1 and obj2.

Where do you see that?  I couldn't find it.

The point of being able to write your own rich comparison methods is so 
you can control what happens -- there is no "must" about it.  This is 
Python -- do what you want!  :)

~Ethan~

PS
I have a broken sense of humor -- sometimes it works, sometimes it 
doesn't.  My apologies in advance if my attempt at humor was not funny.

[toc] | [prev] | [next] | [standalone]


#5264

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-05-12 22:40 +0200
Message-ID<7378643.eNJFYEL58v@PointedEars.de>
In reply to#5249
Ethan Furman wrote:

> PS
> I have a broken sense of humor -- sometimes it works, sometimes it
> doesn't.  My apologies in advance if my attempt at humor was not funny.

Now that was very unpythonic.  Know where your roots are! :)

-- 
PointedEars

Bitte keine Kopien per E-Mail. / Please do not Cc: me.

[toc] | [prev] | [next] | [standalone]


#5267

FromRoy Smith <roy@panix.com>
Date2011-05-12 13:49 -0700
Message-ID<925edfdd-51c7-400b-af2b-4171779779c8@r35g2000prj.googlegroups.com>
In reply to#5249
On May 12, 2:29 pm, Ethan Furman <et...@stoneleaf.us> wrote:

> While it is wrong (it should have 'built-in' precede the word 'types'),
> it is not wrong in the way you think -- a subclass *is* a type of its
> superclass.

Well, consider this:

class List_A(list):
    "A list subclass"

class List_B(list):
    "Another list subclass"

a = List_A()
b = List_B()
print a == b

It prints "True".  Neither a nor b are a type of the other:

print isinstance(List_A, List_B)
print isinstance(List_B, List_A)

False
False

[toc] | [prev] | [next] | [standalone]


#5268

FromEthan Furman <ethan@stoneleaf.us>
Date2011-05-12 14:48 -0700
Message-ID<mailman.1498.1305236181.9059.python-list@python.org>
In reply to#5267
Roy Smith wrote:
> On May 12, 2:29 pm, Ethan Furman <et...@stoneleaf.us> wrote:
> 
>> While it is wrong (it should have 'built-in' precede the word 'types'),
>> it is not wrong in the way you think -- a subclass *is* a type of its
>> superclass.
> 
> Well, consider this:
> 
> class List_A(list):
>     "A list subclass"
> 
> class List_B(list):
>     "Another list subclass"
> 
> a = List_A()
> b = List_B()
> print a == b
> 
> It prints "True".  Neither a nor b are a type of the other:
> 
> print isinstance(List_A, List_B)
> print isinstance(List_B, List_A)
> 
> False
> False

Okay, considering:
     List_A is a user-defined type.
     List_B is a user-defined type.
     Both are sub-classes of list.
     Corrected documentation (which says 'built-in types' etc, etc) says 
nothing about user-defined types not being able to be equal to each other
     neither List_A nor List_B have overridden the __eq__ method, so 
list.__eq__ will be used...

conclusion:
     if they have equal elements in the same order, they will compare 
equal since they are, in fact, list's

Do you not get the same conclusion?

~Ethan~

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web