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


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

What is the semantics meaning of 'object'?

Started byAdam <jiang.adam@gmail.com>
First post2013-06-22 19:58 -0700
Last post2013-06-23 13:12 -0700
Articles 20 on this page of 67 — 12 participants

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


Contents

  What is the semantics meaning of 'object'? Adam <jiang.adam@gmail.com> - 2013-06-22 19:58 -0700
    Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-23 03:20 +0000
      Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-22 22:27 -0600
        Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-23 05:23 +0000
          Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-22 23:40 -0600
            Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-23 17:29 +0000
              Re: What is the semantics meaning of 'object'? Rotwang <sg552@hotmail.co.uk> - 2013-06-24 02:53 +0100
                Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-24 06:31 +0000
                  Re: What is the semantics meaning of 'object'? Rotwang <sg552@hotmail.co.uk> - 2013-06-24 16:00 +0100
                    Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-24 11:23 -0600
      Re: What is the semantics meaning of 'object'? Adam Jiang <jiang.adam@gmail.com> - 2013-06-23 22:35 +0900
      Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-23 10:15 -0600
        Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-23 16:35 +0000
          Re: What is the semantics meaning of 'object'? Roy Smith <roy@panix.com> - 2013-06-23 12:49 -0400
            Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-23 11:08 -0600
              Re: What is the semantics meaning of 'object'? Roy Smith <roy@panix.com> - 2013-06-23 14:14 -0400
            Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-23 11:18 -0600
              Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-23 17:36 +0000
                Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-23 12:04 -0600
                  Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-23 18:50 +0000
                    Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-23 13:09 -0600
                      Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-24 01:12 +0000
                    Re: What is the semantics meaning of 'object'? Roy Smith <roy@panix.com> - 2013-06-23 15:24 -0400
                      Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-24 01:27 +0000
                        Re: What is the semantics meaning of 'object'? Roy Smith <roy@panix.com> - 2013-06-23 21:38 -0400
                          Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-24 08:06 +0000
                            Re: What is the semantics meaning of 'object'? Roy Smith <roy@panix.com> - 2013-06-24 08:41 -0400
                    Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-24 08:58 -0700
                      Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-24 23:51 +0000
                    Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-24 11:26 -0600
                    Re: What is the semantics meaning of 'object'? Ethan Furman <ethan@stoneleaf.us> - 2013-06-26 13:14 -0700
                      Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-26 23:54 +0000
                        Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-26 19:03 -0600
                        Re: What is the semantics meaning of 'object'? Ethan Furman <ethan@stoneleaf.us> - 2013-06-26 17:38 -0700
            Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-23 18:46 +0000
              Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-23 13:05 -0600
              Re: What is the semantics meaning of 'object'? Ethan Furman <ethan@stoneleaf.us> - 2013-06-26 13:37 -0700
            Re: What is the semantics meaning of 'object'? Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-23 13:33 -0700
          Re: What is the semantics meaning of 'object'? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-06-23 21:33 +0200
          Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-25 11:44 -0600
          Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-25 14:58 -0700
          Re: What is the semantics meaning of 'object'? Chris Angelico <rosuav@gmail.com> - 2013-06-26 08:17 +1000
          Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-25 16:21 -0600
          Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-25 16:25 -0600
          Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-25 15:29 -0700
          Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-25 15:27 -0700
          Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-25 15:38 -0700
          Re: What is the semantics meaning of 'object'? Chris Angelico <rosuav@gmail.com> - 2013-06-26 08:39 +1000
          Re: What is the semantics meaning of 'object'? Chris Angelico <rosuav@gmail.com> - 2013-06-26 08:47 +1000
          Re: What is the semantics meaning of 'object'? Chris Angelico <rosuav@gmail.com> - 2013-06-26 08:57 +1000
            Re: What is the semantics meaning of 'object'? Rotwang <sg552@hotmail.co.uk> - 2013-06-26 16:16 +0100
              Re: What is the semantics meaning of 'object'? Chris Angelico <rosuav@gmail.com> - 2013-06-27 01:23 +1000
          Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-25 17:07 -0600
          Re: What is the semantics meaning of 'object'? Chris Angelico <rosuav@gmail.com> - 2013-06-26 09:08 +1000
          Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-25 17:10 -0600
          Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-25 16:19 -0700
            Re: What is the semantics meaning of 'object'? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-26 08:36 +0000
            Re: What is the semantics meaning of 'object'? alex23 <wuwei23@gmail.com> - 2013-06-28 10:19 +1000
              Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-28 11:55 -0700
          Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-25 16:00 -0700
          Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-25 18:19 -0600
          Re: What is the semantics meaning of 'object'? Mark Janssen <dreamingforward@gmail.com> - 2013-06-25 18:07 -0700
          Re: What is the semantics meaning of 'object'? Chris Angelico <rosuav@gmail.com> - 2013-06-26 17:25 +1000
          Re: What is the semantics meaning of 'object'? Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-26 02:53 -0600
          Re: What is the semantics meaning of 'object'? Chris Angelico <rosuav@gmail.com> - 2013-06-26 09:54 +1000
          Re: What is the semantics meaning of 'object'? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-06-26 12:56 +0200
        Re: What is the semantics meaning of 'object'? Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-23 13:12 -0700

Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#49001

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-23 13:09 -0600
Message-ID<mailman.3734.1372014610.3114.python-list@python.org>
In reply to#48999
On Sun, Jun 23, 2013 at 12:50 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> What else would you call a function that does lookups on the current
> object's superclasses?

Well, as James Knight points out in the "Super Considered Harmful"
article, the equivalent in Dylan is called "next-method", which isn't
a valid identifier in Python but seems like a reasonable starting
point.

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


#49019

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-24 01:12 +0000
Message-ID<51c79ceb$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#49001
On Sun, 23 Jun 2013 13:09:21 -0600, Ian Kelly wrote:

> On Sun, Jun 23, 2013 at 12:50 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> What else would you call a function that does lookups on the current
>> object's superclasses?
> 
> Well, as James Knight points out in the "Super Considered Harmful"
> article, the equivalent in Dylan is called "next-method", which isn't a
> valid identifier in Python but seems like a reasonable starting point.


I don't believe it is. Dylan's next-method is an implicit, automatically 
generated method parameter (a little like Python's "self") which holds 
the current value of the next method in the inheritance chain. Unlike 
super, it's only defined inside methods, because it is an implicit 
parameter to each method. It does not return a proxy object like Python's 
super, it's merely an alias to the next method in the chain (or Dylan's 
equivalent of False, when there is no such method), so you can't use it 
for arbitrary attribute lookups like you can with super.

I am not an expert on Dylan, but I'm pretty sure the above is correct. 
Here are some definitive references:

http://opendylan.org/books/drm/Method_Dispatch#HEADING-50-32

http://opendylan.org/documentation/intro-dylan/objects.html


next-method and super can be used for similar things, but they work in 
completely different ways, and next-method is quite limited compared to 
super. But suppose super had been named "next_method", as you suggest. 
Given a class C and an instance c, if I say `x = next_method(C, c)`, 
which method is x the next method of?

That's a trick question, of course. x is not a method at all, it is a 
proxy object such that when you do attribute lookup on it, it will return 
the appropriate attribute.



-- 
Steven

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


#49003

FromRoy Smith <roy@panix.com>
Date2013-06-23 15:24 -0400
Message-ID<roy-B77F2D.15241423062013@70-1-84-166.pools.spcsdns.net>
In reply to#48999
In article <51c74373$0$29999$c3e8da3$5496439d@news.astraweb.com>,
 Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:

> On Sun, 23 Jun 2013 12:04:35 -0600, Ian Kelly wrote:
> 
> > On Sun, Jun 23, 2013 at 11:36 AM, Steven D'Aprano
> > <steve+comp.lang.python@pearwood.info> wrote:
> >> On Sun, 23 Jun 2013 11:18:41 -0600, Ian Kelly wrote:
> >>
> >>> Incidentally, although super() is useful, it's not perfect, and this
> >>> is one of my grievances with it: that a user can, based upon the name,
> >>> draw an inaccurate assumption about what it does without reading or
> >>> fully understanding the documentation on it, which might then result
> >>> in misusing it.
> >>
> >> Wait a second... are you saying that the Python developers created an
> >> advanced language feature relating to multiple inheritance, one of the
> >> most complex OOP concepts around, so difficult that most other
> >> languages simply prohibit it completely, and it wasn't instantly and
> >> correctly intuited by every single programmer based only on the name?
> >> Oh my stars, somebody call Ranting Rick, he needs to write a PyWart
> >> post to expose this scandal!!!
> > 
> > Mostly I'm saying that super() is badly named.
> 
> 
> What else would you call a function that does lookups on the current 
> object's superclasses?

Well, mro_lookup() would have been a better choice.  Super() has an 
obvious meaning, which just happens to be wrong.

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


#49021

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-24 01:27 +0000
Message-ID<51c7a087$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#49003
On Sun, 23 Jun 2013 15:24:14 -0400, Roy Smith wrote:

> In article <51c74373$0$29999$c3e8da3$5496439d@news.astraweb.com>,
>  Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
 
>> What else would you call a function that does lookups on the current
>> object's superclasses?
> 
> Well, mro_lookup() would have been a better choice.  Super() has an
> obvious meaning, which just happens to be wrong.

This "obvious but wrong" meaning isn't the least bit obvious to me. Care 
to give me a hint? The only thing I can think of is:

- if you are familiar with single inheritance;

- but unfamiliar with multiple inheritance;

- and you make the incorrect assumption that there can be only one 
superclass of a given class;

- then you might assume that super means "return the superclass of this 
class" (or possibly instance). 

I don't think that counts as "obvious". Or at least not "intuitive" :-)


In any case, I don't think that the name mro_lookup is appropriate. It's 
misleading because it suggests that you pass something to be looked up, 
like a class, or perhaps an attribute name:

mro_lookup(starting_class, target_class)

mro_lookup(starting_class, 'method_name')



-- 
Steven

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


#49022

FromRoy Smith <roy@panix.com>
Date2013-06-23 21:38 -0400
Message-ID<roy-AFBB56.21383323062013@70-1-84-166.pools.spcsdns.net>
In reply to#49021
In article <51c7a087$0$29999$c3e8da3$5496439d@news.astraweb.com>,
 Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:

> On Sun, 23 Jun 2013 15:24:14 -0400, Roy Smith wrote:
> 
> > In article <51c74373$0$29999$c3e8da3$5496439d@news.astraweb.com>,
> >  Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
>  
> >> What else would you call a function that does lookups on the current
> >> object's superclasses?
> > 
> > Well, mro_lookup() would have been a better choice.  Super() has an
> > obvious meaning, which just happens to be wrong.
> 
> This "obvious but wrong" meaning isn't the least bit obvious to me. Care 
> to give me a hint? The only thing I can think of is:
> 
> - if you are familiar with single inheritance;

True.

> - but unfamiliar with multiple inheritance;

False.  Although, I'm pretty sure that all the times I've used MI (in 
both Python and C++), it was of the mix-in variety.

> - then you might assume that super means "return the superclass of this 
> class" (or possibly instance). 

That's exactly what I assumed.  And, since you correctly surmised that 
that's what I would assume, I would suggest that it was pretty obvious 
to you too.  Of course, given that assumption, it was not at all clear 
what it would do in a class with multiple ancestors.

> I don't think that counts as "obvious". Or at least not "intuitive" :-)

Obvious is in the mind of the observer.

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


#49039

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-24 08:06 +0000
Message-ID<51c7fe14$0$29973$c3e8da3$5496439d@news.astraweb.com>
In reply to#49022
On Sun, 23 Jun 2013 21:38:33 -0400, Roy Smith wrote:

> In article <51c7a087$0$29999$c3e8da3$5496439d@news.astraweb.com>,
>  Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
> 
>> On Sun, 23 Jun 2013 15:24:14 -0400, Roy Smith wrote:
>> 
>> > In article <51c74373$0$29999$c3e8da3$5496439d@news.astraweb.com>,
>> >  Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
>>  
>> >> What else would you call a function that does lookups on the current
>> >> object's superclasses?
>> > 
>> > Well, mro_lookup() would have been a better choice.  Super() has an
>> > obvious meaning, which just happens to be wrong.
>> 
>> This "obvious but wrong" meaning isn't the least bit obvious to me.
>> Care to give me a hint? The only thing I can think of is:
>> 
>> - if you are familiar with single inheritance;
> 
> True.
> 
>> - but unfamiliar with multiple inheritance;
> 
> False.  Although, I'm pretty sure that all the times I've used MI (in
> both Python and C++), it was of the mix-in variety.

Mixins are such a limited version of MI that it's often not even counted 
as MI, and even when it is, being familiar with mixins is hardly 
sufficient to count yourself as familiar with MI. That's kind of like me 
saying I'm familiar with life in Italy on the strength of a three-week 
holiday back in 1982 :-)

If you still think of "the" superclass, then you haven't done enough MI 
to learn better :-)

 
>> - then you might assume that super means "return the superclass of this
>> class" (or possibly instance).
> 
> That's exactly what I assumed.  And, since you correctly surmised that
> that's what I would assume, I would suggest that it was pretty obvious
> to you too.  Of course, given that assumption, it was not at all clear
> what it would do in a class with multiple ancestors.

That's exactly why it *isn't* obvious. Too many assumptions need to be 
made, and questions left unanswered, for the conclusion to be obvious. 
Just because some people might jump to an unjustified conclusion, doesn't 
mean that the conclusion is obvious. That's like saying that it's 
"obvious" that the sun goes around the earth, because that's what it 
looks like. What would it look like if it was the other way around?



>> I don't think that counts as "obvious". Or at least not "intuitive" :-)
> 
> Obvious is in the mind of the observer.

Well that's obvious :-)




-- 
Steven

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


#49043

FromRoy Smith <roy@panix.com>
Date2013-06-24 08:41 -0400
Message-ID<roy-CA2DF2.08415224062013@70-1-84-166.pools.spcsdns.net>
In reply to#49039
In article <51c7fe14$0$29973$c3e8da3$5496439d@news.astraweb.com>,
 Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:

> Mixins are such a limited version of MI that it's often not even counted 
> as MI, and even when it is, being familiar with mixins is hardly 
> sufficient to count yourself as familiar with MI.

OK, fair enough.

> >> - then you might assume that super means "return the superclass of this
> >> class" (or possibly instance).
> > 
> > That's exactly what I assumed.  And, since you correctly surmised that
> > that's what I would assume, I would suggest that it was pretty obvious
> > to you too.  Of course, given that assumption, it was not at all clear
> > what it would do in a class with multiple ancestors.
> 
> That's exactly why it *isn't* obvious. Too many assumptions need to be 
> made, and questions left unanswered, for the conclusion to be obvious.

I think we're using different definitions of "obvious".  I'm using it to 
mean, "What you would conclude from a first look at a problem".  The 
fact that it is proven to be wrong upon closer examination doesn't 
change the fact that it's obvious.

> That's like saying that it's "obvious" that the sun goes around the 
> earth, because that's what it looks like. What would it look like if 
> it was the other way around?

Well, it is obvious.  It's just wrong, based on our current 
understanding.  Humans have been theorizing about how the heavenly 
bodies work for thousands of years.  It's only in the past 400 that 
they're figured out how the solar system works.

So, to bring this back to Python, the goal of designing 
easy-to-understand things is that the obvious explanation also happens 
to be the correct one.  Giving super() the name that it has failed at 
this.

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


#49055

FromMark Janssen <dreamingforward@gmail.com>
Date2013-06-24 08:58 -0700
Message-ID<mailman.3751.1372089511.3114.python-list@python.org>
In reply to#48999
>> Mostly I'm saying that super() is badly named.
>
> What else would you call a function that does lookups on the current
> object's superclasses?

^.  You make a symbol for it.  ^__init__(foo, bar)

-- 
MarkJ
Tacoma, Washington

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


#49111

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-24 23:51 +0000
Message-ID<51c8db7f$0$29973$c3e8da3$5496439d@news.astraweb.com>
In reply to#49055
On Mon, 24 Jun 2013 08:58:23 -0700, Mark Janssen wrote:

>>> Mostly I'm saying that super() is badly named.
>>
>> What else would you call a function that does lookups on the current
>> object's superclasses?
> 
> ^.  You make a symbol for it.  ^__init__(foo, bar)

If you want Perl, you can find it here:

http://www.perl.org/


Or even more scary:

https://en.wikipedia.org/wiki/APL_syntax_and_symbols



^ won't do the job, because it's already used for bitwise-xor. I suppose 
that *technically* it could be used as either a binary or unary operator, 
like +, -, *, **, but I don't think it could be used as both an operator 
and an identifier.



-- 
Steven

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


#49058

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-24 11:26 -0600
Message-ID<mailman.3753.1372095166.3114.python-list@python.org>
In reply to#48999
On Mon, Jun 24, 2013 at 9:58 AM, Mark Janssen <dreamingforward@gmail.com> wrote:
>>> Mostly I'm saying that super() is badly named.
>>
>> What else would you call a function that does lookups on the current
>> object's superclasses?
>
> ^.  You make a symbol for it.  ^__init__(foo, bar)

On the one hand, eww.

On the other hand, with the changes to super in Python 3 to make it
more magical, it might as well be syntax.

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


#49277

FromEthan Furman <ethan@stoneleaf.us>
Date2013-06-26 13:14 -0700
Message-ID<mailman.3902.1372279084.3114.python-list@python.org>
In reply to#48999
On 06/23/2013 11:50 AM, Steven D'Aprano wrote:
> On Sun, 23 Jun 2013 12:04:35 -0600, Ian Kelly wrote:
>
>> On Sun, Jun 23, 2013 at 11:36 AM, Steven D'Aprano
>> <steve+comp.lang.python@pearwood.info> wrote:
>>> On Sun, 23 Jun 2013 11:18:41 -0600, Ian Kelly wrote:
>>>
>>>> Incidentally, although super() is useful, it's not perfect, and this
>>>> is one of my grievances with it: that a user can, based upon the name,
>>>> draw an inaccurate assumption about what it does without reading or
>>>> fully understanding the documentation on it, which might then result
>>>> in misusing it.
>>>
>>> Wait a second... are you saying that the Python developers created an
>>> advanced language feature relating to multiple inheritance, one of the
>>> most complex OOP concepts around, so difficult that most other
>>> languages simply prohibit it completely, and it wasn't instantly and
>>> correctly intuited by every single programmer based only on the name?
>>> Oh my stars, somebody call Ranting Rick, he needs to write a PyWart
>>> post to expose this scandal!!!
>>
>> Mostly I'm saying that super() is badly named.
>
>
> What else would you call a function that does lookups on the current
> object's superclasses?

Well, I would call it super().  Trouble is, that is not all that super() does.  Going back to Ian's example:

> On 06/23/2013 10:08 AM, Ian Kelly wrote:
>>
>> class Base1(object):
>>     def __init__(self, foo, **kwargs):
>>        super(Base1, self).__init__(**kwargs)
>>
>> class Base2(object):
>>     def __init__(self, bar, **kwargs):
>>        super(Base2, self).__init__(**kwargs)
>>
>> class Derived(Base1, Base2):
>>     def __init__(self, **kwargs):
>>        super(Derived, self).__init__(**kwargs)

Notice how Base1 calls super(), but depending on circumstances, it could by Base2 that super() calls.  Surely you are 
not suggesting that Base2 is therefore an ancestor of Base1?

It's too late to change the name now, but pretending there is no good and valid reason for confusion doesn't help.

--
~Ethan~

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


#49288

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-26 23:54 +0000
Message-ID<51cb7f3e$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#49277
On Wed, 26 Jun 2013 13:14:44 -0700, Ethan Furman wrote:

> On 06/23/2013 11:50 AM, Steven D'Aprano wrote:

>> What else would you call a function that does lookups on the current
>> object's superclasses?
> 
> Well, I would call it super().  Trouble is, that is not all that super()
> does.  Going back to Ian's example:
> 
>> On 06/23/2013 10:08 AM, Ian Kelly wrote:
>>>
>>> class Base1(object):
>>>     def __init__(self, foo, **kwargs):
>>>        super(Base1, self).__init__(**kwargs)
>>>
>>> class Base2(object):
>>>     def __init__(self, bar, **kwargs):
>>>        super(Base2, self).__init__(**kwargs)
>>>
>>> class Derived(Base1, Base2):
>>>     def __init__(self, **kwargs):
>>>        super(Derived, self).__init__(**kwargs)
> 
> Notice how Base1 calls super(), but depending on circumstances, it could
> by Base2 that super() calls.  Surely you are not suggesting that Base2
> is therefore an ancestor of Base1?

No. But "the current object" is not Base1, but an instance of Derived, 
and Base2 *is* an ancestor of Derived. Perhaps if I had said "self" 
instead of current object, you wouldn't have made this error. If so, I 
apologise for confusing you.

When your inheritance chain begins from an instance of Base1, Base2 
methods will never be called. It is only when the chain begins from 
Derived that Base2 may be called, which is exactly as it should be.


> It's too late to change the name now, but pretending there is no good
> and valid reason for confusion doesn't help.

The confusion is not with the name, or what super does, but with 
inheritance itself.


-- 
Steven

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


#49290

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-26 19:03 -0600
Message-ID<mailman.3910.1372295027.3114.python-list@python.org>
In reply to#49288
On Wed, Jun 26, 2013 at 5:54 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> No. But "the current object" is not Base1, but an instance of Derived,
> and Base2 *is* an ancestor of Derived. Perhaps if I had said "self"
> instead of current object, you wouldn't have made this error. If so, I
> apologise for confusing you.

If I am reading a class definition and see the code
super().__init__(), and I am not familiar with super() and do not
bother to go look it up in the docs because it looks "obvious" (or
perhaps I have read a tutorial that simply mentions that super() is
used to call methods from a superclass and elides over the details) --
my assumption is not going to be that super() is looking into
superclasses relative to the class of self, but more simply that
super() is looking into superclasses relative to the class that I'm
currently reading.

Why?  Because that's the way that "super" works in every other
language I know of that has it.

Java: super looks depth-first from the contextual class (no multiple
inheritance allowed)
Ruby: super looks depth-first from the contextual class (no multiple
inheritance allowed)
Objective-C: super looks depth-first from the contextual class (no
multiple inheritance allowed)
Perl 5: by default, super looks depth-first from the contextual class
(multiple inheritance IS allowed; the C3 linearization (MRO) CAN be
used, but it must first be explicitly enabled with a pragma directive)

Now if you're coming from Java, Ruby, or Objective-C and reading a
Python super() statement, then hopefully you will stop and think,
"Hey, wait a minute.  [Other language] doesn't have multiple
inheritance and Python does, so how does super() work here?"  More
likely though you're not even thinking about multiple inheritance when
you read that statement, and you just assume that it works exactly
like the super keyword that you're used to, and you move on.

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


#49291

FromEthan Furman <ethan@stoneleaf.us>
Date2013-06-26 17:38 -0700
Message-ID<mailman.3911.1372296393.3114.python-list@python.org>
In reply to#49288
On 06/26/2013 04:54 PM, Steven D'Aprano wrote:
> On Wed, 26 Jun 2013 13:14:44 -0700, Ethan Furman wrote:
>
>> On 06/23/2013 11:50 AM, Steven D'Aprano wrote:
>
>>> What else would you call a function that does lookups on the current
>>> object's superclasses?
>>
>> Well, I would call it super().  Trouble is, that is not all that super()
>> does.  Going back to Ian's example:
>>
>>> On 06/23/2013 10:08 AM, Ian Kelly wrote:
>>>>
>>>> class Base1(object):
>>>>      def __init__(self, foo, **kwargs):
>>>>         super(Base1, self).__init__(**kwargs)
>>>>
>>>> class Base2(object):
>>>>      def __init__(self, bar, **kwargs):
>>>>         super(Base2, self).__init__(**kwargs)
>>>>
>>>> class Derived(Base1, Base2):
>>>>      def __init__(self, **kwargs):
>>>>         super(Derived, self).__init__(**kwargs)
>>
>> Notice how Base1 calls super(), but depending on circumstances, it could
>> by Base2 that super() calls.  Surely you are not suggesting that Base2
>> is therefore an ancestor of Base1?
>
> No. But "the current object" is not Base1, but an instance of Derived,
> and Base2 *is* an ancestor of Derived. Perhaps if I had said "self"
> instead of current object, you wouldn't have made this error. If so, I
> apologise for confusing you.

No apology necessary.  I understand both inheritance and super fairly well, and you did not confuse me.


> When your inheritance chain begins from an instance of Base1, Base2
> methods will never be called. It is only when the chain begins from
> Derived that Base2 may be called, which is exactly as it should be.

Absolutely.  That doesn't change the fact that when writing Base1 you are still using the word 'super', and hopefully 
remembering that even though it's named 'super' it may in fact call an object that is sideways from where you're at now 
and have absolutely no relation to Base1's ancestors.


>> It's too late to change the name now, but pretending there is no good
>> and valid reason for confusion doesn't help.
>
> The confusion is not with the name, or what super does, but with
> inheritance itself.

Good names are important because a good name can help alleviate confusion.  A bad name can exacerbate it.  Given the 
terminology of superclasses and subclasses, naming a function 'super' that can in fact call another class that is in no 
way the superclass of the class in which it is written, can easily cause confusion.

--
~Ethan~

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


#48998

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-23 18:46 +0000
Message-ID<51c7426f$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#48991
On Sun, 23 Jun 2013 12:49:42 -0400, Roy Smith wrote:

> One thing I've never understood about Python 2.x's multiple inheritance
> (mostly because I almost never use it) is how you do something like
> this:
> 
> class Base1(object):
>    def __init__(self, foo):
>       self.foo = foo
> 
> class Base2(object):
>    def __init__(self, bar):
>       self.bar = bar
> 
> class Derived(Base1, Base2):
>    def __init__(self, foo, bar):
>       # now what???
> 
> I need to call __init__() in both of my base classes.  I don't see how
> super() can do that for me.

It doesn't, and it can't, because your classes are not cooperative. The 
problem is, Derived.__init__ needs to call two super methods, but both of 
them require different arguments. If this was an ordinary method, you'd 
probably see the flaw straight away:

class Artist:
    def draw(self, painting): ...

class Gambler:
    def draw(self, cards): ...

class GamblingArtist(Gambler, Artist):
    def draw(self, painting, cards):
        ...


Here you've got two completely different actions that merely share the 
same name, is it really sensible to have *one* method try to do both? And 
if so, you certainly can't expect an automated call to work out which 
argument goes to which superclass. So here's a place where cooperative 
multiple inheritance  doesn't work, and you're reduced to either manually 
calling the methods (and hoping that they don't, in turn, end up in some 
sort of diamond inheritance diagram, which would be bad), or else you 
have to redesign your classes to be more cooperative.

This is one of the reasons why many languages simply prohibit multiple 
inheritance outright, except perhaps for mixins, or at least require that 
all methods have compatible signatures.

All is not lost, there are ways to make your classes cooperative. The 
trick is to have your classes' __init__ methods ignore keyword arguments 
they don't know what to do with. object used to do the same thing, but it 
no longer does, so you need to add an extra class just before object to 
swallow any args before they read object.


class Blocker(object):
    def __init__(self, **kwargs):
        # Block kwargs from reaching object
        super(Blocker, self).__init__()

class Base1(Blocker):
    def __init__(self, foo, **kwargs):
        self.foo = foo
        super(Base1, self).__init__(**kwargs)

class Base2(Blocker):
    def __init__(self, bar, **kwargs):
        self.bar = bar
        super(Base2, self).__init__(**kwargs)

class Derived(Base1, Base2):
    def __init__(self, foo, bar):
        super(Derived, self).__init__(foo=foo, bar=bar)


This may seem like a lot of work, but nobody said that cooperative 
multiple inheritance with different method signatures was easy!

The reality is, multiple inheritance is *hard*. Mixins and traits remove 
most of the problems, so if all you've ever used MI for is mixing in new 
behaviour, you won't get just how hard it really is. The best way to do 
MI is not to do it at all. But if you have to use it, then super is the 
only way to do it *right*. Anything else, and you're almost certainly 
either duplicating what super would do, or you've got bugs in your code.

Anyway, here are some links about super:

Super considered Super:
http://rhettinger.wordpress.com/2011/05/26/super-considered-super/

Here's a set of three posts, written quite a long time ago but still 
relevant, dissecting super in gory detail:

http://www.artima.com/weblogs/viewpost.jsp?thread=236275
http://www.artima.com/weblogs/viewpost.jsp?thread=236278
http://www.artima.com/weblogs/viewpost.jsp?thread=237121

and a more recent update:

http://www.artima.com/weblogs/viewpost.jsp?thread=281127

and a counter-argument, provocatively titled "Super considered Harmful", 
although the author backs away from this claim, since it turns out that 
the problems are not *super* but multiple inheritance itself.

https://fuhm.net/super-harmful/

Despite telling people not to use super, James Knight doesn't actually 
give them a better alternative. I believe this is because he can't -- 
super is the worst solution to multiple inheritance except for all the 
others.



-- 
Steven

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


#49000

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-23 13:05 -0600
Message-ID<mailman.3733.1372014378.3114.python-list@python.org>
In reply to#48998
On Sun, Jun 23, 2013 at 12:46 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> All is not lost, there are ways to make your classes cooperative. The
> trick is to have your classes' __init__ methods ignore keyword arguments
> they don't know what to do with. object used to do the same thing, but it
> no longer does, so you need to add an extra class just before object to
> swallow any args before they read object.
>
>
> class Blocker(object):
>     def __init__(self, **kwargs):
>         # Block kwargs from reaching object
>         super(Blocker, self).__init__()

I don't like the idea of doing this with a cooperative __init__
method.  If any keyword arguments were passed that weren't consumed,
that is probably a bug, and this just swallows the exception instead
of reporting it.

Of course, if you're doing cooperative inheritance with some other
method that doesn't exist on object, then this technique is necessary
to prevent the topmost class from trying to call that method on object
and erroring out.

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


#49276

FromEthan Furman <ethan@stoneleaf.us>
Date2013-06-26 13:37 -0700
Message-ID<mailman.3901.1372279058.3114.python-list@python.org>
In reply to#48998
On 06/23/2013 12:05 PM, Ian Kelly wrote:
> On Sun, Jun 23, 2013 at 12:46 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> All is not lost, there are ways to make your classes cooperative. The
>> trick is to have your classes' __init__ methods ignore keyword arguments
>> they don't know what to do with. object used to do the same thing, but it
>> no longer does, so you need to add an extra class just before object to
>> swallow any args before they read object.
>>
>>
>> class Blocker(object):
>>      def __init__(self, **kwargs):
>>          # Block kwargs from reaching object
>>          super(Blocker, self).__init__()
>
> I don't like the idea of doing this with a cooperative __init__
> method.  If any keyword arguments were passed that weren't consumed,
> that is probably a bug, and this just swallows the exception instead
> of reporting it.

+1

Z
> Of course, if you're doing cooperative inheritance with some other
> method that doesn't exist on object, then this technique is necessary
> to prevent the topmost class from trying to call that method on object
> and erroring out.

But in that case the Blocker wouldn't call super since it is acting as the base class.

--
~Ethan~

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


#49005

FromRick Johnson <rantingrickjohnson@gmail.com>
Date2013-06-23 13:33 -0700
Message-ID<7f1df95b-ae39-4254-be14-df9989d8cf50@googlegroups.com>
In reply to#48991
On Sunday, June 23, 2013 11:49:42 AM UTC-5, Roy Smith wrote:

> For what it's worth, I never bother to inherit from object
> unless I know there's something I need from new style
> classes.  Undoubtedly, this creates a disturbance in The
> Force, but such is life.

Well, in Python 3000, if you don't explicitly inherit from
"object", Python (aka: Guido's Master Control Program) is
going to implicitly do it for you; so i would suggest you be
explicit for the sake of the reader.

PS: I love how people say so confidently:

  "In Python 3, inheriting from object is optional!"

Obviously they don't understand the definition of optional.

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


#49154

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-06-23 21:33 +0200
Message-ID<mailman.3823.1372164608.3114.python-list@python.org>
In reply to#48990
Op 23-06-13 18:35, Steven D'Aprano schreef:
> On Sun, 23 Jun 2013 10:15:38 -0600, Ian Kelly wrote:
>
>> If you're worried about efficiency, you can also explicitly name the
>> superclass in order to call the method directly, like:
>>
>>          A.__init__(self, arg)
>
> Please don't. This is false economy. The time you save will be trivial,
> the overhead of inheritance is not going to be the bottleneck in your
> code, and by ignoring super, you only accomplish one thing:
>
> - if you use your class in multiple inheritance, it will be buggy.

Which is why I don't understand that the python standard library still
contains that kind of code. At least it did in 3.2 and I saw nothing
in the 3.3 release notes that would make me suspect this has changed.

-- 
Antoon Pardon

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


#49175

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-25 11:44 -0600
Message-ID<mailman.3839.1372182747.3114.python-list@python.org>
In reply to#48990
On Sun, Jun 23, 2013 at 1:33 PM, Antoon Pardon
<antoon.pardon@rece.vub.ac.be> wrote:
> Op 23-06-13 18:35, Steven D'Aprano schreef:
>> Please don't. This is false economy. The time you save will be trivial,
>> the overhead of inheritance is not going to be the bottleneck in your
>> code, and by ignoring super, you only accomplish one thing:
>>
>> - if you use your class in multiple inheritance, it will be buggy.
>
>
> Which is why I don't understand that the python standard library still
> contains that kind of code. At least it did in 3.2 and I saw nothing
> in the 3.3 release notes that would make me suspect this has changed.

This bothers me as well.  If you look at Raymond Hettinger's "super()
considered super" article, he includes the (correct) advice that
super() needs to be used at every level of the call chain.  At the end
of the article, he offers this example to show how "easy" multiple
inheritance can be:

from collections import Counter, OrderedDict

class OrderedCounter(Counter, OrderedDict):
     'Counter that remembers the order elements are first seen'
     def __repr__(self):
         return '%s(%r)' % (self.__class__.__name__,
                            OrderedDict(self))
     def __reduce__(self):
         return self.__class__, (OrderedDict(self),)

oc = OrderedCounter('abracadabra')

Which is pretty cool in its simplicity, but here's the rub (which I
have previously noted on this list): OrderedDict doesn't use super.
Counter does, but not cooperatively; it just calls super().__init__()
with no arguments.  So the fact that this example works at all is
basically luck.

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


Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →

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


csiph-web