Attack a sacred Python Cow

Derek Martin code at pizzashack.org
Sun Jul 27 23:39:18 EDT 2008


On Sun, Jul 27, 2008 at 09:39:26PM +0200, Bruno Desthuilliers wrote:
> >As for the latter part of #3, self (or some other variable) is
> >required in the parameter list of object methods,
> 
> It's actually the parameter list of the *function* that is used as the 
> implementation of a method. Not quite the same thing. 

The idea that Python behaves this way is new to me.  For example, the
tutorials make no mention of it:

  http://docs.python.org/tut/node11.html#SECTION0011300000000000000000

The Python reference manual has very little to say about classes,
indeed.  If it's discussed there, it's buried somewhere I could not
easily find it.

> consistency mandates that the target object of the method is part of
> the parameter list of the *function*, since that's how you make
> objects availables to a function.

Fair enough, but I submit that this distinction is abstruse, and
poorly documented, and also generally not something the average
application developer should want to or have to care about... it's of
interest primarily to computer scientists and language enthusiasts.
The language should prefer to hide such details from the people using
it.

> >however when the method is *called*, it is omitted.
> 
> Certainly not. 

Seems not so certain to me...  We disagree, even after your careful
explanation.  See below.

> You need to lookup the corresponding attribute *on a given object*
> to get the method. Whether you write
> 
>   some_object.some_method()
> 
> or
> 
>   some_function(some_object)
> 
> you still need to explicitely mention some_object.

But these two constructs are conceptually DIFFERENT, whether or not
their implementation is the same or similar.  The first says that
some_method is defined within the name space of some_object.  The
second says that some_object is a parameter of some_function...    

Namespace != parameter!!!!!!!!!

To many people previously familiar with OO programming in other
languages (not just Java or C++), but not intimately familiar with
Python's implementation details, the first also implies that
some_method is inherently part of some_object, in which case
explicitly providing a parameter to pass in the object naturally seems
kind of crazy.  The method can and should have implicit knowledge of
what object it has been made a part.  Part of the point of using
objects is that they do have special knowledge of themselves... they
(generally) manipulate data that's part of the object.  Conceptually,
the idea that an object's methods can be defined outside of the scope
of the object, and need to be told what object they are part
of/operating on is somewhat nonsensical...

> >Thus when an object method is called, it must be called with one fewer
> >arguments than those which are defined.   This can be confusing,
> >especially to new programmers.
> 
> This is confusing as long as you insist on saying that what you 
> "def"ined is a method - which is not the case.

I can see now the distinction, but please pardon my prior ignorance,
since the documentation says it IS the case, as I pointed out earlier.
Furthermore, as you described, defining the function within the scope
of a class binds a name to the function and then makes it a method of
the class.  Once that happens, *the function has become a method*.

To be perfectly honest, the idea that an object method can be defined
outside the scope of an object (i.e. where the code has no reason to
have any knowledge of the object) seems kind of gross to me... another
Python wart.  One which could occasionally be useful I suppose, but a
wart nonetheless.  This seems inherently not object-oriented at all,
for reasons I've already stated.  It also strikes me as a feature
designed to encourage bad programming practices.

Even discounting that, if Python had a keyword which referenced the
object of which a given peice of code was a part, e.g. self, then a
function written to be an object method could use this keyword *even
if it is defined outside of the scope of a class*.  The self keyword,
once the function was bound to an object, would automatically refer to
the correct object.  If the function were called outside of the
context of an object, then referencing self would result in an
exception.

You'll probably argue that this takes away your ability to define a
function and subsequently use it both as a stand-alone function and
also as a method.  I'm OK with that -- while it might occasionally
be useful, I think if you feel the need to do this, it probably means
your program design is wrong/bad.  More than likely what you really
needed was to define a class that had the function as a method, and
another class (or several) that inherits from the first.


> The point is that you don't get access to the object "within itself". 
> You get access to an object *within a function*.

Thus methods are not really methods at all, which would seem to
suggest that Python's OO model is inherently broken (albeit by design,
and perhaps occasionally to good effect).
 
> The fact that a function is defined within a class statement doesn't 
> imply any "magic", 

It does indeed -- it does more than imply.  It states outright that
the function is defined within the namespace of that object, and as
such that it is inherently part of that object.  So why should it need
to be explicitly told about the object of which it is already a part?

It further does indeed imply, to hordes of programmers experienced
with OO programming in other languages, that as a member, property,
attribute, or what ever you care to call it, of the object, it should
have special knowledge about the object of which it is a part.  It
just so happens that in Python, this implication is false.

> IOW : there's one arguably good reason to drop the target object from 
> functions used as methods implementation, which is to make Python looks 
> more like Java

No, that's not the reason.  I don't especially like Java, nor do I use
it.  The reason is to make the object model behave more intuitively.

>, and there's at least two good reason to keep it the way it is,
>which are simplicity (no special case) and consistency (no special
>case).

Clearly a lot of people find that it is less simple TO USE.  The point
of computers is to make hard things easier... if there is a task that
is annoying, or tedious, or repetitive, it should be done by code, not
humans.  This is something that Python should do automatically for its
users.

-- 
Derek D. Martin
http://www.pizzashack.org/
GPG Key ID: 0x81CFE75D

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20080727/2d54a19f/attachment.sig>


More information about the Python-list mailing list