Why self?

Alex Martelli aleax at aleax.it
Wed Jul 10 03:42:51 EDT 2002


Robb Shecter wrote:

> Alex Martelli wrote:
> 
>>>Well, I'd say that an object understanding the message I send to it, or
>>>being the type of object I think it is - success or failure - surely is
>>>a big difference!  Sort of the name of the whole game...
>> 
>> An object can "understand" (well...) the message (out of metaphor: be
>> able to supply the attribute or method you're asking of it) WITHOUT
>> "being the type you think it is".  This is called POLYMORPHISM, and
>> IS the whole game.
> 
> Damn!  The all-caps are out.  And to beat that, I've been blindsided by
> a red herring!
> 
> 1. So you're uhh... agreeing but not?

I'm not agreeing that "being the type you think it is" matters.

> 2. I'm down w/ polymorphism, man!  I'm all over over it.  There's a big
> difference between type and class, for starters, and 'type' as in

Not in Python 2.2:

>>> class X(object): pass
...
>>> x = X()
>>> type(x)
<class '__main__.X'>
>>>

See?  The type of x IS class X -- in Python 2.2.

> 'implements an interface' is what I'm talking about.

Pleased to meet you, Mr Humpty-Dumpty -- take care about sitting
on walls, pray.

You can certainly find areas of human endeavour where 'type' and 'class'
have been defined in the ways you prefer.  But, we're talking about
Python -- if you're using terms in wildly different ways from the way
Python uses it, you have to define the fact, of course.  They don't
mean "just what you want them to mean, no more, no less".

It's not particularly sensible in Python to think of a concept of
"interface" as "type".  Whenever you bind on x a new attribute you're
then changing its type...?  That doesn't make much sense -- it's not
a fruitful concept, either practically or conceptually.  It may be
useful for other, more rigid languages, but not here.

Basically when you try to call x.foo() the distinctions that
matter are:

1. any object either has an attribute foo, or not.  If x is in the
   set of objects not having attribute foo, this raises AttributeError

2. objects that have an attribute foo can have it callable, or not.  If
   x is in the set of objects whose attribute foo is not callable,
   this raises TypeError with suitable contents.

3. objects with a callable foo attribute may let you call it without
   arguments, or not.  If not, TypeError again, with different
   contents (about what numbers of argument you should supply).

Any of these points can be changed by any operation on x.  If x's
type (class) supplies a foo, x can "un-supply" it only via
__getattribute__ (which must be class-supplied and flexible
enough to support that...), so (1) is sometimes hard to get away
from -- but 2 / 3 are trivial (the type/class would not only
have to supply foo but do it via a property that stops rebinding --
a tall order, not impossible but practically never encountered).

It's therefore quite irrelevant for you to state x's type or
class.

What you DO want to assert is: x has an attribute named foo,
callable without arguments.

How you assert this is with statement
        x.foo()
There are no other general ways to assert this, although you
may break some part of this down carefully:
        hasattr(x, 'foo') and callable(getattr(x,'foo'))
(the 'callable without arguments' part is harder...).

Surprise!  That's EXACTLY the statement you need to use here.

Can't get any more explicit than this...:-).


> No, you don't know me, but I know OO.  :-)

If you really do know OO in the context of a reasonably dynamic
language (Python's quite dynamic, but some other OO languages
such as Ruby are even more so), then your statement about Python's
"implicitness" here is inexcusable.  I'd rather explain it as an
understandable confusion due do unfamiliarity with the context,
but, if you insist...


Alex




More information about the Python-list mailing list