Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #84665 > unrolled thread
| Started by | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| First post | 2015-01-27 21:12 +0100 |
| Last post | 2015-01-27 18:11 -0800 |
| Articles | 20 on this page of 63 — 17 participants |
Back to article view | Back to comp.lang.python
An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-27 21:12 +0100
Re: An object is an instance (or not)? Ethan Furman <ethan@stoneleaf.us> - 2015-01-27 12:36 -0800
Re: An object is an instance (or not)? André Roberge <andre.roberge@gmail.com> - 2015-01-27 12:50 -0800
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-27 22:06 +0100
Re: An object is an instance (or not)? André Roberge <andre.roberge@gmail.com> - 2015-01-27 13:38 -0800
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-27 22:43 +0100
Re: An object is an instance (or not)? André Roberge <andre.roberge@gmail.com> - 2015-01-27 13:49 -0800
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-27 22:58 +0100
Re: An object is an instance (or not)? Ben Finney <ben+python@benfinney.id.au> - 2015-01-28 09:32 +1100
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 18:55 +1100
Re: An object is an instance (or not)? Ben Finney <ben+python@benfinney.id.au> - 2015-01-28 22:20 +1100
Re: An object is an instance (or not)? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-01-27 23:12 +0000
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-28 01:52 +0100
Re: An object is an instance (or not)? Marko Rauhamaa <marko@pacujo.net> - 2015-01-28 07:25 +0200
Re: An object is an instance (or not)? Rustom Mody <rustompmody@gmail.com> - 2015-01-27 21:53 -0800
Re: An object is an instance (or not)? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-01-28 05:57 +0000
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-28 11:48 +0100
Re: An object is an instance (or not)? random832@fastmail.us - 2015-01-28 00:37 -0500
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 19:45 +1100
Re: An object is an instance (or not)? Devin Jeanpierre <jeanpierreda@gmail.com> - 2015-01-27 21:43 -0800
Re: An object is an instance (or not)? random832@fastmail.us - 2015-01-28 01:01 -0500
Re: An object is an instance (or not)? Rustom Mody <rustompmody@gmail.com> - 2015-01-27 22:22 -0800
Re: An object is an instance (or not)? Ben Finney <ben+python@benfinney.id.au> - 2015-01-28 18:03 +1100
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 19:48 +1100
Re: An object is an instance (or not)? Ben Finney <ben+python@benfinney.id.au> - 2015-01-28 17:59 +1100
Re: An object is an instance (or not)? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-01-28 20:21 +1300
Re: An object is an instance (or not)? Ben Finney <ben+python@benfinney.id.au> - 2015-01-28 18:48 +1100
Re: An object is an instance (or not)? random832@fastmail.us - 2015-01-28 12:08 -0500
Re: An object is an instance (or not)? Rustom Mody <rustompmody@gmail.com> - 2015-01-28 18:29 -0800
Re: An object is an instance (or not)? Ned Batchelder <ned@nedbatchelder.com> - 2015-01-27 18:22 -0500
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-28 01:17 +0100
Re: An object is an instance (or not)? Chris Angelico <rosuav@gmail.com> - 2015-01-28 11:30 +1100
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-28 01:35 +0100
Re: An object is an instance (or not)? alex23 <wuwei23@gmail.com> - 2015-01-28 14:44 +1000
Re: An object is an instance (or not)? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-01-28 23:33 +1300
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 22:52 +1100
Re: An object is an instance (or not)? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-01-29 19:22 +1300
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-29 18:16 +1100
Re: An object is an instance (or not)? Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-29 08:48 -0700
Re: An object is an instance (or not)? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-01-30 22:07 +1300
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-31 10:45 +1100
Re: An object is an instance (or not)? Ned Batchelder <ned@nedbatchelder.com> - 2015-01-27 21:21 -0500
Re: An object is an instance (or not)? Rustom Mody <rustompmody@gmail.com> - 2015-01-27 18:52 -0800
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 20:16 +1100
Re: An object is an instance (or not)? Chris Angelico <rosuav@gmail.com> - 2015-01-28 21:01 +1100
Re: An object is an instance (or not)? Rick Johnson <rantingrickjohnson@gmail.com> - 2015-01-29 14:22 -0800
Re: An object is an instance (or not)? Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-27 19:15 -0700
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 20:28 +1100
Re: An object is an instance (or not)? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-01-28 23:33 +1300
Re: An object is an instance (or not)? Grant Edwards <invalid@invalid.invalid> - 2015-01-28 00:23 +0000
Re: An object is an instance (or not)? Ben Finney <ben+python@benfinney.id.au> - 2015-01-28 10:39 +1100
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-28 01:24 +0100
Re: An object is an instance (or not)? Ben Finney <ben+python@benfinney.id.au> - 2015-01-28 12:00 +1100
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-28 02:14 +0100
Re: An object is an instance (or not)? alex23 <wuwei23@gmail.com> - 2015-01-28 14:47 +1000
Re: An object is an instance (or not)? Rustom Mody <rustompmody@gmail.com> - 2015-01-27 21:23 -0800
Re: An object is an instance (or not)? random832@fastmail.us - 2015-01-28 00:44 -0500
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 20:21 +1100
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 20:17 +1100
Re: An object is an instance (or not)? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-28 20:09 +1100
Re: An object is an instance (or not)? Chris Angelico <rosuav@gmail.com> - 2015-01-28 10:42 +1100
Re: An object is an instance (or not)? Mario Figueiredo <marfig@gmail.com> - 2015-01-28 01:31 +0100
Re: An object is an instance (or not)? Rustom Mody <rustompmody@gmail.com> - 2015-01-27 18:11 -0800
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | random832@fastmail.us |
|---|---|
| Date | 2015-01-28 01:01 -0500 |
| Message-ID | <mailman.18204.1422424871.18130.python-list@python.org> |
| In reply to | #84670 |
On Wed, Jan 28, 2015, at 00:43, Devin Jeanpierre wrote: > On Tue, Jan 27, 2015 at 9:37 PM, <random832@fastmail.us> wrote: > > Sub itself is not a Sub object, it is a type object. "instance" is > > implicit in the phrase "foo object". > > Yes. Unfortunately, it's still not really completely clear. "Sub > instance" would avoid this confusion for everyone. It really is completely clear. Nobody is confused but you.
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-01-27 22:22 -0800 |
| Message-ID | <d7d48e3b-c278-40f7-b13f-ee7ac968a6f1@googlegroups.com> |
| In reply to | #84719 |
On Wednesday, January 28, 2015 at 11:31:46 AM UTC+5:30, random wrote: > On Wed, Jan 28, 2015, at 00:43, Devin Jeanpierre wrote: > > On Tue, Jan 27, 2015 at 9:37 PM, random832 wrote: > > > Sub itself is not a Sub object, it is a type object. "instance" is > > > implicit in the phrase "foo object". > > > > Yes. Unfortunately, it's still not really completely clear. "Sub > > instance" would avoid this confusion for everyone. > > It really is completely clear. Nobody is confused but you. I think I can count 4 people OP trying to show the confusion (maybe confusedly) Ben agreeing that some terminology could be straightened out Devin agreeing with Ben Me(Rusi): Prefer a not so cavalier adjective-noun equivalencing
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-01-28 18:03 +1100 |
| Message-ID | <mailman.18206.1422428706.18130.python-list@python.org> |
| In reply to | #84720 |
Rustom Mody <rustompmody@gmail.com> writes: > Me(Rusi): Prefer a not so cavalier adjective-noun equivalencing I can sympathise with that preference. It really is a lost cause, though; the English language just works that way. We use nouns as verbs, nouns as modifiers, adjectives as nouns; and rather than wish it were not so, we must to take care to express ourselves to avoid unintended ambiguity — especially in writing. And *especially* in writing terse formal error messages. The English language is imperfect, but it's what we have. Live with it. -- \ “The manager has personally passed all the water served here.” | `\ —hotel, Acapulco | _o__) | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-01-28 19:48 +1100 |
| Message-ID | <54c8a257$0$12906$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #84719 |
random832@fastmail.us wrote: > On Wed, Jan 28, 2015, at 00:43, Devin Jeanpierre wrote: >> On Tue, Jan 27, 2015 at 9:37 PM, <random832@fastmail.us> wrote: >> > Sub itself is not a Sub object, it is a type object. "instance" is >> > implicit in the phrase "foo object". >> >> Yes. Unfortunately, it's still not really completely clear. "Sub >> instance" would avoid this confusion for everyone. > > It really is completely clear. Nobody is confused but you. Ironically, your denial of a pretty clear case of ambiguity demonstrates that if anyone is confused, it is you. In an earlier thread, Mario demonstrated an obvious example of confusing error message due to the object/instance ambiguity, where the error message states that Sub doesn't have a method when it actually does. It is an *instance of Sub*, not the Sub object itself, which lacks the method. -- Steve
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-01-28 17:59 +1100 |
| Message-ID | <mailman.18205.1422428385.18130.python-list@python.org> |
| In reply to | #84670 |
random832@fastmail.us writes: > On Wed, Jan 28, 2015, at 00:43, Devin Jeanpierre wrote: > > On Tue, Jan 27, 2015 at 9:37 PM, <random832@fastmail.us> wrote: > > > Sub itself is not a Sub object, it is a type object. "instance" is > > > implicit in the phrase "foo object". > > > > Yes. Unfortunately, it's still not really completely clear. "Sub > > instance" would avoid this confusion for everyone. > > It really is completely clear. Nobody is confused but you. You have no justification to claim that, and it's hostile and dismissive to claim it so assertively. I'll freely admit to finding “'Foo' object” ambiguous. It can reasonably be interpreted to mean either “a 'Foo' object” (⇒ “an object of class 'Foo'”), or “the 'Foo' object” (⇒ “the object referred to by the name 'Foo'”). The error message which inspired this thread needs improvement, as I've said already. Let's not dismiss anyone's experience without good reason. -- \ “When people believe that they have absolute knowledge, with no | `\ test in reality, this [the Auschwitz crematorium] is how they | _o__) behave.” —Jacob Bronowski, _The Ascent of Man_, 1973 | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-01-28 20:21 +1300 |
| Message-ID | <cirgvaFtgueU1@mid.individual.net> |
| In reply to | #84670 |
Mario Figueiredo wrote: > That error message has me start that thread arguing that the error is > misleading because the Sub object does have the __bases__ attribute. > It's the Sub instance object that does not have it. > > Some of the answers that were given argued that in Python object = > instance. No, they pointed out that *in that particular sentence* the word "object" was being used in a way that's more or less synonymous with "instance". But that doesn't mean the two words are perfectly interchangeable in all English sentences. Sometimes one is better than the other. I prefer to use the word "instance" when I'm talking about an instance *of* something, e.g. "an instance of Foo" or "a Foo instance". If I'm not mentioning a class, I just use the word "object". So I would argue that "Sub instance has no attribute..." is a marginally clearer way to word that message. Which means, I think, that I'm more or less agreeing with you, but *not* because of objects not always being instances in Python. On the contrary, it's precisely because all objects *are* instances that using the word "instance" on its own in place of "object" is pointless -- it doesn't convey any extra information. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-01-28 18:48 +1100 |
| Message-ID | <mailman.18208.1422431305.18130.python-list@python.org> |
| In reply to | #84670 |
Devin Jeanpierre <jeanpierreda@gmail.com> writes: > […] as Ben Finney pointed out. (BTW I agree with literally every > single thing he said in this thread, it's really amazing.) Hmm, writing that doesn't annoy somebody is not worth writing [0]. It shouldn't annoy *everyone* though, so I'm glad to know you can agree with me this time :-) [0] often attributed to Kingley Amis, as “If you can't annoy somebody, there's little point in writing.” though I can't find the source for that aphorism. -- \ “Facts are stubborn things; and whatever may be our wishes, our | `\ inclinations, or the dictates of our passion, they cannot alter | _o__) the state of facts and evidence.” —John Adams, 1770-12-04 | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | random832@fastmail.us |
|---|---|
| Date | 2015-01-28 12:08 -0500 |
| Message-ID | <mailman.18223.1422464917.18130.python-list@python.org> |
| In reply to | #84670 |
On Wed, Jan 28, 2015, at 01:59, Ben Finney wrote: > You have no justification to claim that, and it's hostile and dismissive > to claim it so assertively. Sorry about that - I was tired and had just read through the whole thread at once. > I'll freely admit to finding “'Foo' object” ambiguous. It can reasonably > be interpreted to mean either “a 'Foo' object” (⇒ “an object of class > 'Foo'”), or “the 'Foo' object” (⇒ “the object referred to by the name > 'Foo'”). The error message which inspired this thread needs improvement, > as I've said already. Most objects do not have an idea of their name, though. Assigning an object to a new name doesn't change the object, either.
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-01-28 18:29 -0800 |
| Message-ID | <b77efd62-6b15-4107-bee7-ceb59b9b17b6@googlegroups.com> |
| In reply to | #84767 |
On Wednesday, January 28, 2015 at 10:39:34 PM UTC+5:30, rand...@fastmail.us wrote: > On Wed, Jan 28, 2015, at 01:59, Ben Finney wrote: > > You have no justification to claim that, and it's hostile and dismissive > > to claim it so assertively. > > Sorry about that - I was tired and had just read through the whole > thread at once. Heh Sweet! The lost art of gracefully saying sorry
[toc] | [prev] | [next] | [standalone]
| From | Ned Batchelder <ned@nedbatchelder.com> |
|---|---|
| Date | 2015-01-27 18:22 -0500 |
| Message-ID | <mailman.18191.1422400930.18130.python-list@python.org> |
| In reply to | #84665 |
On 1/27/15 3:12 PM, Mario Figueiredo wrote: > This is a follow up from a previous discussion in which it is argued > that the following code produces the correct error message terminology, > considering that in Python an object is also an instance. I don't know what the difference is between "object" and "instance". An object is an instance of a class. The two words are interchangeable as far as I know. > An instance IS an object. On that we can agree. After all, everything in > Python is an object. Even classes are. We can even pass them as function > arguments: > > >>> class Sub: > pass > > >>> def show(aClass): > print(type(aClass)) > > >>> show(Sub) > <class 'type'> > > The problem is that an object isn't always an instance. The word > instance in OOP has a very formal meaning. A common mistake is to believe that "OOP" is a well-defined term. It's not it's a collection of ideas that are expressed slightly differently in each language. > In programming languages in > which the classes aren't fully realized objects, it is ok to speak of > 'instance' and 'object' interchangeably. I don't know what a "not fully realized object" is. > But even then, sometimes the > term 'object instance' is preferred, as a way to separate these > 'instances' from other variable instances that may not be created from > class definitions (e.g. C++ built-in types). > > The fact that in Python classes are objects, should not just eliminate > this distinction. The OOP terminology should exist beyond the language > implementing it. It facilitates discourse and helps transmiting concepts > when describing your ideas to another programmer. And because in python, > classes are of the type 'type' and they exist as fully realized objects, > is no excuse to make a distinction between them and their own fully > realized instances. The language implementation details should not exist > as a way for us to freely reformulate long standing terms. > > Because, from my own study of Python, I've came to realize that the > distinction between objects and instances of objects actually exists. In > Python, class objects cannot participate in OOP, only their instances. What does "participate in OOP" mean? > This is why I say that even in Python, where a class is an object, an > object is not always an instance. The language itself forces that > distinction. -- Ned Batchelder, http://nedbatchelder.com
[toc] | [prev] | [next] | [standalone]
| From | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| Date | 2015-01-28 01:17 +0100 |
| Message-ID | <MPG.2f3248ebaccae0069896a9@nntp.aioe.org> |
| In reply to | #84684 |
In article <mailman.18191.1422400930.18130.python-list@python.org>,
ned@nedbatchelder.com says...
>
> A common mistake is to believe that "OOP" is a well-defined term. It's
> not it's a collection of ideas that are expressed slightly differently
> in each language.
A common mistake is thinking just because OOP has different
implementations, it doesn't have a cohesive set of well described rules
and its own well defined terminology.
> I don't know what a "not fully realized object" is.
A fully realized object, in an object oriented paradigm, is an object
containing or pointing to data and the methods to act on that data. It's
an instance of a class.
A *not* fully realized object is possible in Python, since Classes are
first-class objects, despite not being able to participate in OOP.
>
> What does "participate in OOP" mean?
Means the object is capable of participating in inheritance and/or
polymorphism. An instance of an object is capable of doing so, per its
class definitions. Whereas a Python class object is not.
>>> class Master:
def func(self):
pass
>>> class Sub(Master):
pass
>>> Sub.func()
TypeError: func() missing 1 required positional argument: 'self'
But somehow I think you knew the answer to all these questions and were
instead being snarky.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-01-28 11:30 +1100 |
| Message-ID | <mailman.18195.1422405040.18130.python-list@python.org> |
| In reply to | #84688 |
On Wed, Jan 28, 2015 at 11:17 AM, Mario Figueiredo <marfig@gmail.com> wrote: > Means the object is capable of participating in inheritance and/or > polymorphism. An instance of an object is capable of doing so, per its > class definitions. Whereas a Python class object is not. > > >>> class Master: > def func(self): > pass > > >>> class Sub(Master): > pass > > >>> Sub.func() > TypeError: func() missing 1 required positional argument: 'self' > > But somehow I think you knew the answer to all these questions and were > instead being snarky. I have no idea what you're proving here. You just showed that the class has a function attached to it, and you didn't provide enough arguments to it. And types have their own set of attributes and methods: >>> dir(type) ['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__dir__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__prepare__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__text_signature__', '__weakrefoffset__', 'mro'] Most of those are inherited from object, but some aren't. What are you demonstrating? ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| Date | 2015-01-28 01:35 +0100 |
| Message-ID | <MPG.2f324d0d46ba9afc9896ac@nntp.aioe.org> |
| In reply to | #84691 |
In article <mailman.18195.1422405040.18130.python-list@python.org>, rosuav@gmail.com says... > > On Wed, Jan 28, 2015 at 11:17 AM, Mario Figueiredo <marfig@gmail.com> wrote: > > Means the object is capable of participating in inheritance and/or > > polymorphism. An instance of an object is capable of doing so, per its > > class definitions. Whereas a Python class object is not. > > > > >>> class Master: > > def func(self): > > pass > > > > >>> class Sub(Master): > > pass > > > > >>> Sub.func() > > TypeError: func() missing 1 required positional argument: 'self' > > > I have no idea what you're proving here. You just showed that the > class has a function attached to it, and you didn't provide enough > arguments to it. And types have their own set of attributes and > methods: > I admit it was a contrived example. I couldn't think of a way to demonstrate that a class object does not participate in its own inheritance rules. Only instances of it can.
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2015-01-28 14:44 +1000 |
| Message-ID | <ma9pen$8ds$1@dont-email.me> |
| In reply to | #84693 |
On 28/01/2015 10:35 AM, Mario Figueiredo wrote:
> I admit it was a contrived example. I couldn't think of a way to
> demonstrate that a class object does not participate in its own
> inheritance rules. Only instances of it can.
A class object isn't an instance of itself, it's an instance of the
Class (to be extact, 'type') class. Method dispatching will also
traverse the base classes when refering to the class object, too:
>>> class Master:
... @classmethod
... def func(cls):
... return cls
...
>>> class Sub(Master):
... pass
...
>>> type(Sub)
<class 'type'>
>>> Sub.func()
<class '__main__.Sub'>
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-01-28 23:33 +1300 |
| Message-ID | <cirs87F1tdrU2@mid.individual.net> |
| In reply to | #84693 |
Mario Figueiredo wrote:
> I couldn't think of a way to
> demonstrate that a class object does not participate in its own
> inheritance rules. Only instances of it can.
I think I may see where your reasoning is going astray.
You think that an instance "inherits" methods from its
class in the same way that a subclass inherits methods
from its base class.
But thinking of the instance-class relationship as
an inheritance relationship is misleading. It's more
accurate to say that a class *defines* the methods
that its instances have. The class inherits methods
from its base class, but those methods still apply to
instances of the class, not the class itself.
That doesn't mean the class itself can't be given
methods, though. The methods of the class are defined
by its metaclass, and the metaclass inherits methods
from *its* base class, etc.
Here's a diagram:
+------+ +------------+
| type | | base class |
+------+ +------------+
^ ^
| subclass of | subclass of
| |
+-----------+ +-------+ +----------+
| metaclass |<-------------| class |<-------------| instance |
+-----------+ instance of +-------+ instance of +----------+
It should be clear from this that the relationship
between an instance and its class is exactly the same
as that between a class and its metaclass, including
inheritance relationships.
The diagram can be extended indefinitely far to the
left -- the metaclass could be an instance of a
meta-metaclass, etc. (Although there's an old standing
joke in the Python world that metaclasses make your
head explode, so I hate to think what a meta-metaclass
would do -- probably take out a whole floor of the
office building you work in. Meta-meta-metaclasses are
right out.)
--
Greg
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-01-28 22:52 +1100 |
| Message-ID | <54c8cd8f$0$12975$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #84740 |
Gregory Ewing wrote:
> Mario Figueiredo wrote:
>> I couldn't think of a way to
>> demonstrate that a class object does not participate in its own
>> inheritance rules. Only instances of it can.
>
> I think I may see where your reasoning is going astray.
> You think that an instance "inherits" methods from its
> class in the same way that a subclass inherits methods
> from its base class.
In fairness, "inherit" is standard terminology for the way instances get
their behaviour from their class.
Also, you can override methods *on the instance*:
py> class Parrot(object):
... def talk(self):
... print("Polly wants a cracker!")
...
py> polly = Parrot()
py> polly.talk()
Polly wants a cracker!
py> from types import MethodType
py> polly.talk = MethodType(
... lambda self: print("Polly wants a spam sandwich!"), polly)
py> polly.talk()
Polly wants a spam sandwich!
> But thinking of the instance-class relationship as
> an inheritance relationship is misleading. It's more
> accurate to say that a class *defines* the methods
> that its instances have. The class inherits methods
> from its base class, but those methods still apply to
> instances of the class, not the class itself.
I won't speak for other OOP models, but I don't think that is true in
Python. In Python, obj.talk performs the following (grossly simplified)
process:
* search the instance for an attribute "talk"
* search the class
* search all the base classes
* fail
(simplified because I have ignored the roles of __getattr__ and
__getattribute__, of metaclasses, and the descriptor protocol)
That's more or less the same as what happens whether obj is a class object
or a non-class object. I don't know what attribute lookup *literally* uses
the exact same code for looking up attributes on an instance or a class,
but it wouldn't surprise me if it does.
> That doesn't mean the class itself can't be given
> methods, though. The methods of the class are defined
> by its metaclass, and the metaclass inherits methods
> from *its* base class, etc.
The normal way of giving a class methods that are callable from the class is
to define them on the class with the classmethod or staticmethod
decorators. Using a metaclass is usually overkill :-)
> Here's a diagram:
>
> +------+ +------------+
> | type | | base class |
> +------+ +------------+
> ^ ^
> | subclass of | subclass of
> | |
> +-----------+ +-------+ +----------+
> | metaclass |<-------------| class |<-------------| instance |
> +-----------+ instance of +-------+ instance of +----------+
>
> It should be clear from this that the relationship
> between an instance and its class is exactly the same
> as that between a class and its metaclass, including
> inheritance relationships.
>
> The diagram can be extended indefinitely far to the
> left -- the metaclass could be an instance of a
> meta-metaclass, etc. (Although there's an old standing
> joke in the Python world that metaclasses make your
> head explode, so I hate to think what a meta-metaclass
> would do -- probably take out a whole floor of the
> office building you work in. Meta-meta-metaclasses are
> right out.)
An early essay on Python metaclasses was subtitled "The Killer-Joke".
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-01-29 19:22 +1300 |
| Message-ID | <ciu1taFjekrU1@mid.individual.net> |
| In reply to | #84743 |
Steven D'Aprano wrote: > In fairness, "inherit" is standard terminology for the way instances get > their behaviour from their class. I'm not sure that's true, but even if it is, it's not the same kind of inheritance relationship as exists between a class and a base class, which was my point. > Also, you can override methods *on the instance*: I wouldn't call that a method -- it's just an instance attribute that happens to be a function. You can tell it's not a method because it doesn't get a 'self' argument. > In Python, obj.talk performs the following (grossly simplified) > process: > > * search the instance for an attribute "talk" > * search the class > * search all the base classes > * fail > > (simplified because I have ignored the roles of __getattr__ and > __getattribute__, of metaclasses, and the descriptor protocol) By ignoring the descriptor protocol, you're simplifying away something very important. It's the main thing that makes the instance-of relation different from the subclass-of relation. > The normal way of giving a class methods that are callable from the class is > to define them on the class with the classmethod or staticmethod > decorators. Using a metaclass is usually overkill :-) True, but I was trying to illustrate the symmetry between classes and instances, how the classic OOP ideas of Smalltalk et al are manifest in Python, and to show that classes *can* "participate fully in OOP" just like any other objects if you want them to. Python's "class methods" are strange beasts that don't have an equivalent in the classic OOP model, so they would only have confused matters. And there are cases where you *do* need a metaclass, such as giving a __dunder__ method to a class, so it's useful to know how to do it just in case. > An early essay on Python metaclasses was subtitled "The Killer-Joke". Quick, translate this post into German before anyone sees too much of it! -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-01-29 18:16 +1100 |
| Message-ID | <54c9de44$0$12915$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #84800 |
Gregory Ewing wrote:
> Steven D'Aprano wrote:
>
>> In fairness, "inherit" is standard terminology for the way instances get
>> their behaviour from their class.
>
> I'm not sure that's true, but even if it is, it's
> not the same kind of inheritance relationship as
> exists between a class and a base class, which was
> my point.
I suspect that in Python it actually is, but I don't understand the
implementation of attribute look-ups well enough to be sure.
>> Also, you can override methods *on the instance*:
>
> I wouldn't call that a method -- it's just an instance
> attribute that happens to be a function. You can tell
> it's not a method because it doesn't get a 'self' argument.
Actually, if you look at my example, you will see that it is a method and it
does get the self argument. Here is the critical code again:
from types import MethodType
polly.talk = MethodType(
lambda self: print("Polly wants a spam sandwich!"), polly)
The MethodType constructor takes a function and an instance, and returns a
method bound to that instance.
>> In Python, obj.talk performs the following (grossly simplified)
>> process:
>>
>> * search the instance for an attribute "talk"
>> * search the class
>> * search all the base classes
>> * fail
>>
>> (simplified because I have ignored the roles of __getattr__ and
>> __getattribute__, of metaclasses, and the descriptor protocol)
>
> By ignoring the descriptor protocol, you're simplifying
> away something very important. It's the main thing that
> makes the instance-of relation different from the
> subclass-of relation.
That's certainly not correct, because Python had classes and instances
before it had descriptors! Classes and instances go back to pre-1.5 days,
while descriptors were only introduced in 2.2. Besides, descriptors are
handled by the metaclass, so we could write a metaclass that doesn't handle
them.
>> The normal way of giving a class methods that are callable from the class
>> is to define them on the class with the classmethod or staticmethod
>> decorators. Using a metaclass is usually overkill :-)
>
> True, but I was trying to illustrate the symmetry
> between classes and instances, how the classic OOP
> ideas of Smalltalk et al are manifest in Python,
> and to show that classes *can* "participate fully
> in OOP" just like any other objects if you want them
> to. Python's "class methods" are strange beasts that
> don't have an equivalent in the classic OOP model,
> so they would only have confused matters.
Fair point about classmethods.
I think you're actually underestimating how close the symmetry between new-
style classes and instances actually is in Python.
> And there are cases where you *do* need a metaclass,
> such as giving a __dunder__ method to a class, so it's
> useful to know how to do it just in case.
I don't understand this. I write dunder methods all the time. Ah wait, I
think I've got it. If you want (say) your class object itself to support
(say) the + operator, it isn't enough to write a __add__ method on the
class, you have to write it on the metaclass.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-01-29 08:48 -0700 |
| Message-ID | <mailman.18265.1422546549.18130.python-list@python.org> |
| In reply to | #84802 |
On Thu, Jan 29, 2015 at 12:16 AM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > Besides, descriptors are > handled by the metaclass, so we could write a metaclass that doesn't handle > them. Maybe this doesn't affect your argument, but they're actually handled by the class's __getattribute__, not by the metaclass. >>> class MyMeta(type): ... def __getattribute__(cls, attr): ... raise AttributeError(attr) ... >>> class MyClass(metaclass=MyMeta): ... @property ... def spam(self): ... return 42 ... >>> MyClass().spam 42 >>> class MyClass: ... def __getattribute__(self, attr): ... return type(self).__dict__[attr] ... @property ... def spam(self): ... return 42 ... >>> MyClass().spam <property object at 0x7f0603e70598>
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-01-30 22:07 +1300 |
| Message-ID | <cj0vveFck6dU1@mid.individual.net> |
| In reply to | #84802 |
Steven D'Aprano wrote:
> Actually, if you look at my example, you will see that it is a method and it
> does get the self argument. Here is the critical code again:
>
> from types import MethodType
> polly.talk = MethodType(
> lambda self: print("Polly wants a spam sandwich!"), polly)
Doing it by hand is cheating.
> That's certainly not correct, because Python had classes and instances
> before it had descriptors!
Before the descriptor protocol, a subset of its functionality
was hard-wired into the interpreter. There has always been
some magic going on across the instance-class boundary that
doesn't occur across the class-baseclass boundary.
> Ah wait, I
> think I've got it. If you want (say) your class object itself to support
> (say) the + operator, it isn't enough to write a __add__ method on the
> class, you have to write it on the metaclass.
That's right.
--
Greg
[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