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 1 of 4  [1] 2 3 4  Next page →


#48968 — What is the semantics meaning of 'object'?

FromAdam <jiang.adam@gmail.com>
Date2013-06-22 19:58 -0700
SubjectWhat is the semantics meaning of 'object'?
Message-ID<15ba0011-bbf1-42f7-b3ea-1c1d4b70e56b@googlegroups.com>
class FooBar(object):
    def __init__(self):
        ...

Inheritance usually takes a class name to indicate which class is the 'parent' class. However, in the previous example, from a django book, the class actually takes an 'object' like parameter, doesn't it? What is the semantics meaning of such kind of notation?

Thanks,
/Adam

[toc] | [next] | [standalone]


#48972

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-23 03:20 +0000
Message-ID<51c66962$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#48968
On Sat, 22 Jun 2013 19:58:38 -0700, Adam wrote:

> class FooBar(object):
>     def __init__(self):
>         ...
> 
> Inheritance usually takes a class name to indicate which class is the
> 'parent' class. However, in the previous example, from a django book,
> the class actually takes an 'object' like parameter, doesn't it? What is
> the semantics meaning of such kind of notation?

It's not merely notation, "object" is the name of a class. If you type it 
(without quotes) at the interactive interpreter, you will see it is a 
built-in class:

py> object
<class 'object'>


In Python 3, the use of object as base class is optional, but in Python 2 
there is a subtle difference between classes that inherit from object and 
those that don't. The reason for this difference is buried in the mists 
of time, going back to Python 2.2. If you are interested, google on 
"Python unifying types and classes":

https://duckduckgo.com/html/?q=Python+unifying+types+and+classes


As a general rule, unless you actually want "old-style class" behaviour, 
you should always inherit from object (or some other built-in type) in 
Python 2. In Python 3, it doesn't matter.

The differences include:

* property only works in "new-style" classes that inherit from object;

* likewise for super;

* multiple inheritance with old-style classes can be buggy;

* new-style classes may be slightly faster in general;

* on the down side, automatic delegation of special double-underscore 
methods like __getitem__ and __str__ doesn't work with new-style classes.


If none of this means anything to you, be glad, and just inherit from 
object or some other built-in type in all your classes, and all will be 
good.




-- 
Steven

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


#48976

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-22 22:27 -0600
Message-ID<mailman.3724.1371961680.3114.python-list@python.org>
In reply to#48972
On Sat, Jun 22, 2013 at 9:20 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> * on the down side, automatic delegation of special double-underscore
> methods like __getitem__ and __str__ doesn't work with new-style classes.

I actually consider that an up side.  Sure it's inconvenient that you
can't delegate all such methods at once just by overriding
__getattribute__, but it would be more troublesome to *accidentally*
implement such methods because you implemented __getattribute__.  And
then there are methods that really should not be delegated in the
first place, like __del__.

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


#48977

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-23 05:23 +0000
Message-ID<51c68638$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#48976
On Sat, 22 Jun 2013 22:27:10 -0600, Ian Kelly wrote:

> On Sat, Jun 22, 2013 at 9:20 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> * on the down side, automatic delegation of special double-underscore
>> methods like __getitem__ and __str__ doesn't work with new-style
>> classes.
> 
> I actually consider that an up side.  Sure it's inconvenient that you
> can't delegate all such methods at once just by overriding
> __getattribute__, but it would be more troublesome to *accidentally*
> implement such methods because you implemented __getattribute__.  

It's hard to see a case where that would be a bad thing.

1) If the proxied object doesn't include __dunder__ methods, then the 
proxy will just end up up calling the default object dunder methods, 
exactly as if they weren't proxied.

2) If the proxied object does include dunders, then you generally want 
the proxy to call them, with perhaps one or two exceptions, which need to 
be overridden regardless of whether they are dunders or not.


> And
> then there are methods that really should not be delegated in the first
> place, like __del__.

If you're using __del__, you're probably doing something wrong :-)

I suppose that __del__ is a good counter-example, but (1) hardly any 
classes use __del__, and (2) for those that do, it's *way* simpler to 
manually override __del__ in the proxy than to manually delegate every 
dunder method you care about. There are typically a lot of dunder methods 
you care about.

It is not the case that dunder methods cannot be automatically proxied 
because somebody deliberately designed Python to work that way. It's an 
accidental side-effect of the way new-style classes resolve method calls, 
due to decisions made for other reasons having nothing to do with 
delegation. That this accident just happens to have one tiny silver 
lining doesn't change the fact that, overall, it's still a dark cloud.

In classic classes, automatic delegation was a first-class design 
pattern. With new-style classes, it's second-class, and that's a pity.


-- 
Steven

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


#48978

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-22 23:40 -0600
Message-ID<mailman.3725.1371967812.3114.python-list@python.org>
In reply to#48977
On Sat, Jun 22, 2013 at 11:23 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Sat, 22 Jun 2013 22:27:10 -0600, Ian Kelly wrote:
>> I actually consider that an up side.  Sure it's inconvenient that you
>> can't delegate all such methods at once just by overriding
>> __getattribute__, but it would be more troublesome to *accidentally*
>> implement such methods because you implemented __getattribute__.
>
> It's hard to see a case where that would be a bad thing.
>
> 1) If the proxied object doesn't include __dunder__ methods, then the
> proxy will just end up up calling the default object dunder methods,
> exactly as if they weren't proxied.
>
> 2) If the proxied object does include dunders, then you generally want
> the proxy to call them, with perhaps one or two exceptions, which need to
> be overridden regardless of whether they are dunders or not.

Proxying objects is not the only use of __getattribute__.

>> And
>> then there are methods that really should not be delegated in the first
>> place, like __del__.
>
> If you're using __del__, you're probably doing something wrong :-)
>
> I suppose that __del__ is a good counter-example, but (1) hardly any
> classes use __del__, and (2) for those that do, it's *way* simpler to
> manually override __del__ in the proxy than to manually delegate every
> dunder method you care about. There are typically a lot of dunder methods
> you care about.

If you manually override __del__ in the proxy, then as far as the
garbage collector is concerned, your proxy object has a __del__ method
(even if it does nothing), and so it will be treated differently from
an object without a __del__ method.

> It is not the case that dunder methods cannot be automatically proxied
> because somebody deliberately designed Python to work that way. It's an
> accidental side-effect of the way new-style classes resolve method calls,
> due to decisions made for other reasons having nothing to do with
> delegation.

Can you elaborate or provide a link?  I'm curious to know what other
reason there could be for magic methods to behave differently from
normal methods in this regard.

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


#48994

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-23 17:29 +0000
Message-ID<51c7308d$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#48978
On Sat, 22 Jun 2013 23:40:53 -0600, Ian Kelly wrote:

> On Sat, Jun 22, 2013 at 11:23 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> On Sat, 22 Jun 2013 22:27:10 -0600, Ian Kelly wrote:
>>> I actually consider that an up side.  Sure it's inconvenient that you
>>> can't delegate all such methods at once just by overriding
>>> __getattribute__, but it would be more troublesome to *accidentally*
>>> implement such methods because you implemented __getattribute__.
>>
>> It's hard to see a case where that would be a bad thing.
>>
>> 1) If the proxied object doesn't include __dunder__ methods, then the
>> proxy will just end up up calling the default object dunder methods,
>> exactly as if they weren't proxied.
>>
>> 2) If the proxied object does include dunders, then you generally want
>> the proxy to call them, with perhaps one or two exceptions, which need
>> to be overridden regardless of whether they are dunders or not.
> 
> Proxying objects is not the only use of __getattribute__.

Okay, fair point.

Actually, I made a mistake... automatic delegation uses __getattr__, not 
__getattribute__.


>>> And
>>> then there are methods that really should not be delegated in the
>>> first place, like __del__.
>>
>> If you're using __del__, you're probably doing something wrong :-)
>>
>> I suppose that __del__ is a good counter-example, but (1) hardly any
>> classes use __del__, and (2) for those that do, it's *way* simpler to
>> manually override __del__ in the proxy than to manually delegate every
>> dunder method you care about. There are typically a lot of dunder
>> methods you care about.
> 
> If you manually override __del__ in the proxy, then as far as the
> garbage collector is concerned, your proxy object has a __del__ method
> (even if it does nothing), and so it will be treated differently from an
> object without a __del__ method.

Ack, I get that.

A thought comes to mind... perhaps Python ought to treat a class with 
__del__ set to None as if there was no __del__ at all? At the moment the 
garbage collector blindly calls __del__ and gets a TypeError.


>> It is not the case that dunder methods cannot be automatically proxied
>> because somebody deliberately designed Python to work that way. It's an
>> accidental side-effect of the way new-style classes resolve method
>> calls, due to decisions made for other reasons having nothing to do
>> with delegation.
> 
> Can you elaborate or provide a link?  I'm curious to know what other
> reason there could be for magic methods to behave differently from
> normal methods in this regard.

It's an efficiency optimization. I don't quite get the details, but when 
you run something like "a + b", Python doesn't search for __add__ using 
the normal method lookup procedure. That allows it to skip checking the 
instance __dict__, as well as __getattribute__ and __getattr__. End 
result is that it's quite a bit faster than ordinary lookup, but the side-
effect is that the semantics are a little different:

- you can't proxy magic methods automatically;

- __getattribute__ and __getattr__ are only called for explicit attribute 
access, not for implied calls to magic methods;

- you can't override a magic method on a per instance basis.

Note that explicit calls like "obj.__add__(thing)" take the regular 
method lookup, it's just "obj + thing" that takes the shortcut.


-- 
Steven

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


#49024

FromRotwang <sg552@hotmail.co.uk>
Date2013-06-24 02:53 +0100
Message-ID<kq88ga$5b8$1@dont-email.me>
In reply to#48994
On 23/06/2013 18:29, Steven D'Aprano wrote:
> On Sat, 22 Jun 2013 23:40:53 -0600, Ian Kelly wrote:
>> [...]
>>
>> Can you elaborate or provide a link?  I'm curious to know what other
>> reason there could be for magic methods to behave differently from
>> normal methods in this regard.
>
> It's an efficiency optimization. I don't quite get the details, but when
> you run something like "a + b", Python doesn't search for __add__ using
> the normal method lookup procedure. That allows it to skip checking the
> instance __dict__, as well as __getattribute__ and __getattr__.

It's not just an efficiency optimisation, it's actually necessary in 
cases where a dunder method gets called on a type. Consider what happens 
when one calls repr(int), for example - if this tried to call 
int.__repr__() by the normal lookup method, it would call the unbound 
__repr__ method of int with no self argument:

 >>> int.__repr__()
Traceback (most recent call last):
   File "<pyshell#1>", line 1, in <module>
     int.__repr__()
TypeError: descriptor '__repr__' of 'int' object needs an argument

By bypassing the instance-first lookup and going straight to the 
object's type's dictionary, repr(int) instead calls type.__repr__(int), 
which works:

 >>> type.__repr__(int)
"<class 'int'>"

This is explained here:

http://docs.python.org/3.3/reference/datamodel.html#special-lookup

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


#49036

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-24 06:31 +0000
Message-ID<51c7e7ca$0$29973$c3e8da3$5496439d@news.astraweb.com>
In reply to#49024
On Mon, 24 Jun 2013 02:53:06 +0100, Rotwang wrote:

> On 23/06/2013 18:29, Steven D'Aprano wrote:
>> On Sat, 22 Jun 2013 23:40:53 -0600, Ian Kelly wrote:
>>> [...]
>>>
>>> Can you elaborate or provide a link?  I'm curious to know what other
>>> reason there could be for magic methods to behave differently from
>>> normal methods in this regard.
>>
>> It's an efficiency optimization. I don't quite get the details, but
>> when you run something like "a + b", Python doesn't search for __add__
>> using the normal method lookup procedure. That allows it to skip
>> checking the instance __dict__, as well as __getattribute__ and
>> __getattr__.
> 
> It's not just an efficiency optimisation, it's actually necessary in
> cases where a dunder method gets called on a type. Consider what happens
> when one calls repr(int), for example - if this tried to call
> int.__repr__() by the normal lookup method, it would call the unbound
> __repr__ method of int with no self argument:


I don't know about *necessary*, after all, classic classes manage just 
fine in Python 2.x:

py> class OldStyle:
...     def __repr__(self):
...             return "Spam"
... 
py> repr(OldStyle())
'Spam'
py> repr(OldStyle)
'<class __main__.OldStyle at 0xb7553e0c>'


I daresay that there are good reasons why new-style classes don't do the 
same thing, but the point is that had the Python devs had been 
sufficiently interested in keeping the old behaviour, and willing to pay 
whatever costs that would require, they could have done so.

But your point is well taken. It's not just purely a speed optimization.


> This is explained here:
> 
> http://docs.python.org/3.3/reference/datamodel.html#special-lookup


Nice link, thank you.


-- 
Steven

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


#49052

FromRotwang <sg552@hotmail.co.uk>
Date2013-06-24 16:00 +0100
Message-ID<kq9mk2$s6q$1@dont-email.me>
In reply to#49036
On 24/06/2013 07:31, Steven D'Aprano wrote:
> On Mon, 24 Jun 2013 02:53:06 +0100, Rotwang wrote:
>
>> On 23/06/2013 18:29, Steven D'Aprano wrote:
>>> On Sat, 22 Jun 2013 23:40:53 -0600, Ian Kelly wrote:
>>>> [...]
>>>>
>>>> Can you elaborate or provide a link?  I'm curious to know what other
>>>> reason there could be for magic methods to behave differently from
>>>> normal methods in this regard.
>>>
>>> It's an efficiency optimization. I don't quite get the details, but
>>> when you run something like "a + b", Python doesn't search for __add__
>>> using the normal method lookup procedure. That allows it to skip
>>> checking the instance __dict__, as well as __getattribute__ and
>>> __getattr__.
>>
>> It's not just an efficiency optimisation, it's actually necessary in
>> cases where a dunder method gets called on a type. Consider what happens
>> when one calls repr(int), for example - if this tried to call
>> int.__repr__() by the normal lookup method, it would call the unbound
>> __repr__ method of int with no self argument:
>
>
> I don't know about *necessary*, after all, classic classes manage just
> fine in Python 2.x:
>
> py> class OldStyle:
> ...     def __repr__(self):
> ...             return "Spam"
> ...
> py> repr(OldStyle())
> 'Spam'
> py> repr(OldStyle)
> '<class __main__.OldStyle at 0xb7553e0c>'

Point taken. It's also possible to override the __repr__ method of an 
old-style instance and have the change recognised by repr, so repr(x) 
isn't simply calling type(x).__repr__(x) in general.


> I daresay that there are good reasons why new-style classes don't do the
> same thing, but the point is that had the Python devs had been
> sufficiently interested in keeping the old behaviour, and willing to pay
> whatever costs that would require, they could have done so.

Sure, though the above behaviour was probably easier to achieve with 
old-style classes than it would have been with new-style classes because 
all instances of old-style classes have the same type. But I don't doubt 
that you're correct that they could have done it if they wanted.

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


#49057

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-24 11:23 -0600
Message-ID<mailman.3752.1372094681.3114.python-list@python.org>
In reply to#49052
On Mon, Jun 24, 2013 at 9:00 AM, Rotwang <sg552@hotmail.co.uk> wrote:
> On 24/06/2013 07:31, Steven D'Aprano wrote:
>
>> I daresay that there are good reasons why new-style classes don't do the
>> same thing, but the point is that had the Python devs had been
>> sufficiently interested in keeping the old behaviour, and willing to pay
>> whatever costs that would require, they could have done so.
>
>
> Sure, though the above behaviour was probably easier to achieve with
> old-style classes than it would have been with new-style classes because all
> instances of old-style classes have the same type. But I don't doubt that
> you're correct that they could have done it if they wanted.

It seems to me that the important difference with new-style classes is
that they suddenly have metaclasses and are themselves just ordinary
objects, and so it is important that they consistently resolve calls
in the same way that all other objects do.

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


#48980

FromAdam Jiang <jiang.adam@gmail.com>
Date2013-06-23 22:35 +0900
Message-ID<mailman.3726.1371994559.3114.python-list@python.org>
In reply to#48972
> * property only works in "new-style" classes that inherit from object;
> 
> * likewise for super;

Another question raised here is that what is the proper way to refer
to parent class? For example,

class A(object):
        def __init__(self, arg):
                print "A"

class B(A):
        def __init__(self, arg):
                super(B, self).__init__(arg)

Is this correct? As the result, whenever you wanted to refer to a
method in parent class, super() functions has to be called. This seems
inefficient.

How to refer to a field defined in parent class?

Thanks,
/Adam

>On Sun, Jun 23, 2013 at 03:20:02AM +0000, Steven D'Aprano wrote:
> On Sat, 22 Jun 2013 19:58:38 -0700, Adam wrote:
> 
> > class FooBar(object):
> >     def __init__(self):
> >         ...
> > 
> > Inheritance usually takes a class name to indicate which class is the
> > 'parent' class. However, in the previous example, from a django book,
> > the class actually takes an 'object' like parameter, doesn't it? What is
> > the semantics meaning of such kind of notation?
> 
> It's not merely notation, "object" is the name of a class. If you type it 
> (without quotes) at the interactive interpreter, you will see it is a 
> built-in class:
> 
> py> object
> <class 'object'>
> 
> 
> In Python 3, the use of object as base class is optional, but in Python 2 
> there is a subtle difference between classes that inherit from object and 
> those that don't. The reason for this difference is buried in the mists 
> of time, going back to Python 2.2. If you are interested, google on 
> "Python unifying types and classes":
> 
> https://duckduckgo.com/html/?q=Python+unifying+types+and+classes
> 
> 
> As a general rule, unless you actually want "old-style class" behaviour, 
> you should always inherit from object (or some other built-in type) in 
> Python 2. In Python 3, it doesn't matter.
> 
> The differences include:
> 
> * property only works in "new-style" classes that inherit from object;
> 
> * likewise for super;
> 
> * multiple inheritance with old-style classes can be buggy;
> 
> * new-style classes may be slightly faster in general;
> 
> * on the down side, automatic delegation of special double-underscore 
> methods like __getitem__ and __str__ doesn't work with new-style classes.
> 
> 
> If none of this means anything to you, be glad, and just inherit from 
> object or some other built-in type in all your classes, and all will be 
> good.
> 
> 
> 
> 
> -- 
> Steven
> -- 
> http://mail.python.org/mailman/listinfo/python-list

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


#48988

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-23 10:15 -0600
Message-ID<mailman.3729.1372004188.3114.python-list@python.org>
In reply to#48972
On Sun, Jun 23, 2013 at 7:35 AM, Adam Jiang <jiang.adam@gmail.com> wrote:
> Another question raised here is that what is the proper way to refer
> to parent class? For example,
>
> class A(object):
>         def __init__(self, arg):
>                 print "A"
>
> class B(A):
>         def __init__(self, arg):
>                 super(B, self).__init__(arg)
>
> Is this correct? As the result, whenever you wanted to refer to a
> method in parent class, super() functions has to be called. This seems
> inefficient.

Generally, use super() any time you want to refer to a class attribute
(such as a method) in a parent class that is overridden in the child
class. Also note that in Python 3, the call "super(B, self)" can be
condensed to just "super()".

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)

However, super() is generally considered the right way to do this, in
order to avoid repeating the parent class name, for brevity in Python
3, and because it is needed to correctly handle some cases of multiple
inheritance.

> How to refer to a field defined in parent class?

For instance attributes or attributes that haven't been overridden,
just write "self.attribute_name".

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


#48990

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-23 16:35 +0000
Message-ID<51c723b4$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#48988
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.



-- 
Steven

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


#48991

FromRoy Smith <roy@panix.com>
Date2013-06-23 12:49 -0400
Message-ID<roy-4289AA.12494223062013@70-1-84-166.pools.spcsdns.net>
In reply to#48990
In article <51c723b4$0$29999$c3e8da3$5496439d@news.astraweb.com>,
 Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:

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

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.  I assume I would just do:

   def __init__(self, foo, bar):
      Base1.__init__(self, foo)
      Base2.__init__(self, bar)

am I missing something here?

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.

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


#48992

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-23 11:08 -0600
Message-ID<mailman.3730.1372007386.3114.python-list@python.org>
In reply to#48991
On Sun, Jun 23, 2013 at 10:49 AM, Roy Smith <roy@panix.com> 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.  I assume I would just do:
>
>    def __init__(self, foo, bar):
>       Base1.__init__(self, foo)
>       Base2.__init__(self, bar)
>
> am I missing something here?

Yes, you're missing that super() does not simply call the base class,
but rather the next class in the MRO for whatever the type of the
"self" argument is.  If you write the above as:

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)

And then you create an instance of Derived by calling
Derived(foo='foo', bar='bar') and trace the call chain, you find that
Derived.__init__ will call Base1.__init__(foo='foo', bar='bar'), which
extracts its argument and then calls (surprise!)
Base2.__init__(bar='bar'), which again extracts its argument and then
calls object.__init__(), ending the chain.

Of course if you create an instance of Base1, then the Base1 super
call will next call object.__init__ directly, instead of
Base2.__init__.  This happens because Base2 occurs after Base1 in the
MRO for the class Derived, but Base2 does not appear at all in the MRO
for the class Base1.

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


#48997

FromRoy Smith <roy@panix.com>
Date2013-06-23 14:14 -0400
Message-ID<roy-E09022.14141623062013@70-1-84-166.pools.spcsdns.net>
In reply to#48992
In article <mailman.3730.1372007386.3114.python-list@python.org>,
 Ian Kelly <ian.g.kelly@gmail.com> wrote:

> Yes, you're missing that super() does not simply call the base class,
> but rather the next class in the MRO for whatever the type of the
> "self" argument is.  If you write the above as:
> 
> 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)
> 
> And then you create an instance of Derived by calling
> Derived(foo='foo', bar='bar') and trace the call chain, you find that
> Derived.__init__ will call Base1.__init__(foo='foo', bar='bar'), which
> extracts its argument and then calls (surprise!)
> Base2.__init__(bar='bar'), which again extracts its argument and then
> calls object.__init__(), ending the chain.

Mind.  Blown.

I'm tempted to go all Ranting Rick about this being non-obvious, but I 
see you already covered that in another post :-)

The other thing I see here is that to make this work, the base classes 
need to accept **kwargs.  That's kind of annoying, since it means a 
class has to explicitly designed to be multiply-inheritable.

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


#48993

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-23 11:18 -0600
Message-ID<mailman.3731.1372007973.3114.python-list@python.org>
In reply to#48991
On Sun, Jun 23, 2013 at 11:08 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> On Sun, Jun 23, 2013 at 10:49 AM, Roy Smith <roy@panix.com> wrote:
>> am I missing something here?
>
> Yes, you're missing that super() does not simply call the base class,
> but rather the next class in the MRO for whatever the type of the
> "self" argument is.  If you write the above as:

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.  There might still be some code I wrote out there from
when I first started using Python that looks something like:

    def __init__(self):
        super(Base, self).__init__()
        Mixin.__init__(self)

Which is simply wrong, wrong, wrong.

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


#48995

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-23 17:36 +0000
Message-ID<51c73229$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#48993
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!!! 

*wink*


-- 
Steven

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


#48996

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-06-23 12:04 -0600
Message-ID<mailman.3732.1372010720.3114.python-list@python.org>
In reply to#48995
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.

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


#48999

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-23 18:50 +0000
Message-ID<51c74373$0$29999$c3e8da3$5496439d@news.astraweb.com>
In reply to#48996
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?



-- 
Steven

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


Page 1 of 4  [1] 2 3 4  Next page →

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


csiph-web