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


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

An object is an instance (or not)?

Started byMario Figueiredo <marfig@gmail.com>
First post2015-01-27 21:12 +0100
Last post2015-01-27 18:11 -0800
Articles 20 on this page of 63 — 17 participants

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


Contents

  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 →


#84719

Fromrandom832@fastmail.us
Date2015-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]


#84720

FromRustom Mody <rustompmody@gmail.com>
Date2015-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]


#84722

FromBen Finney <ben+python@benfinney.id.au>
Date2015-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]


#84730

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-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]


#84721

FromBen Finney <ben+python@benfinney.id.au>
Date2015-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]


#84723

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2015-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]


#84725

FromBen Finney <ben+python@benfinney.id.au>
Date2015-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]


#84767

Fromrandom832@fastmail.us
Date2015-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]


#84798

FromRustom Mody <rustompmody@gmail.com>
Date2015-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]


#84684

FromNed Batchelder <ned@nedbatchelder.com>
Date2015-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]


#84688

FromMario Figueiredo <marfig@gmail.com>
Date2015-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]


#84691

FromChris Angelico <rosuav@gmail.com>
Date2015-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]


#84693

FromMario Figueiredo <marfig@gmail.com>
Date2015-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]


#84710

Fromalex23 <wuwei23@gmail.com>
Date2015-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]


#84740

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2015-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]


#84743

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-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]


#84800

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2015-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]


#84802

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-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]


#84820

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-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]


#84870

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2015-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