Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #48968 > unrolled thread
| Started by | Adam <jiang.adam@gmail.com> |
|---|---|
| First post | 2013-06-22 19:58 -0700 |
| Last post | 2013-06-23 13:12 -0700 |
| Articles | 20 on this page of 67 — 12 participants |
Back to article view | Back to comp.lang.python
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 →
| From | Adam <jiang.adam@gmail.com> |
|---|---|
| Date | 2013-06-22 19:58 -0700 |
| Subject | What 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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-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]
| From | Rotwang <sg552@hotmail.co.uk> |
|---|---|
| Date | 2013-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-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]
| From | Rotwang <sg552@hotmail.co.uk> |
|---|---|
| Date | 2013-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Adam Jiang <jiang.adam@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-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]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2013-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2013-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-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