Attack a sacred Python Cow

Russ P. Russ.Paielli at gmail.com
Sun Jul 27 18:34:10 EDT 2008


On Jul 27, 3:11 pm, "Russ P." <Russ.Paie... at gmail.com> wrote:
> On Jul 27, 12:39 pm, Bruno Desthuilliers
>
>
>
> <bdesth.quelquech... at free.quelquepart.fr> wrote:
> > Derek Martin a écrit :
>
> > > On Sun, Jul 27, 2008 at 08:19:17AM +0000, Steven D'Aprano wrote:
> > >>> You take the name down to a single letter. As I suggested in an earlier
> > >>> post on this thread, why not take it down to zero letters?
> > >> The question isn't "why not", but "why". The status quo works well as it
> > >> is, even if it isn't perfect. Prove that implicit self is a good idea --
> > >> or at least prove that it is an idea worth considering.
>
> > > Come on, this sounds like a schoolyard argument.  This comes down to a
> > > matter of style, and as such, is impossible to prove.  It's largely a
> > > question of individual preference.
>
> > > That said, the argument in favor is rather simple:
>
> > > 1. This is an extremely common idiom in Python
> > > 2. It is completely unnecessary, and the language does not suffer for
> > >    making it implicit
> > > 3. Making it implicit reduces typing, reduces opportunities for
> > >    mistakes, and arguably increases consistency.
>
> > "arguably", indeed, cf below.
>
> > > 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. And then,
> > 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.
>
> > > however when the
> > > method is *called*, it is omitted.
>
> > Certainly not. 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.
>
> > > It is implied, supplied by Python.
>
> > Neither. The target object is passed to the function by the method
> > object, which is itself returned by the __get__ method of function
> > objects, which is one possible application of the more general
> > descriptor protocol (the same protocol that is used for computed
> > attributes). IOW, there's nothing specific to 'methods' here, just the
> > use of two general features (functions and the descriptor protocol).
> > FWIW, you can write your own callable, and write it so it behave just
> > like a function here:
>
> > import types
>
> > class MyCallable(object):
> >     def __call__(self, obj):
> >         print "calling %s with %s" % (self, obj)
> >     def __get__(self, instance, cls):
> >         return types.MethodType(self.__call__, instance, cls)
>
> > class Foo(object):
> >      bar = MyCallable()
>
> > print Foo.bar
> > f = Foo()
> > f.bar()
>
> > > 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.
>
> > > It can also be argued that it makes the code less ugly, though again,
> > > that's a matter of preference.
>
> > >> It's not enough to show that a change "isn't bad" -- you have to show
> > >> that it is actively good.
>
> > > But he did... he pointed out that *it saves work*, without actually
> > > being bad.  Benefit, without drawback.  Sounds good to me!
>
> > >> "Don't need to look at the method signature" is not an argument in favour
> > >> of implicit self.
>
> > > Yes, actually, it is.
>
> > It isn't, since there's no "method signature" to look at !-)
>
> > >  If there is a well-defined feature of Python
> > > which provides access to the object within itself,
>
> > The point is that you don't get access to the object "within itself".
> > You get access to an object *within a function*.
>
> > The fact that a function is defined within a class statement doesn't
> > imply any "magic", it just creates a function object, bind it to a name,
> > and make that object an attribute of the class. You have the very same
> > result by defining the function outside the class statement and binding
> > it within the class statement, by defining the function outside the
> > class and binding it to the class outside the class statement, by
> > binding the name to a lambda within the class statement etc...
>
> > > then the
> > > opportunities for mistakes when someone decides to use something else
> > > are lessened.
>
> > >> You don't need to look at the method signature when you're using an
> > >> explicit self either.
>
> > > That isn't necessarily true.  If you're using someone else's code, and
> > > they didn't use "self" -- or worse yet, if they chose this variable's
> > > name randomly throughout their classes -- then you may well need to
> > > look back to see what was used.
>
> > > It's bad programming, but the world is full of bad programmers, and we
> > > don't always have the choice not to use their code.  Isn't one of
> > > Python's goals to minimize opportunities for bad programming?
>
> > Nope. That's Java's goal. Python's goals are to maximize opportunities
> > for good programming, which is quite different.
>
> > > Providing a keyword equivalent to self and removing the need to name
> > > it in object methods is one way to do that.
>
> > It's also a way to make Python more complicated than it needs to be. At
> > least with the current state, you define your functions the same way
> > regardless of how they are defined, and the implementation is
> > (relatively) easy to explain. Special-casing functions definition that
> > happens within a class statement would only introduce a special case.
> > Then you'd have to explain why you need to specify the target object in
> > the function's parameters when the function is defined outside the class
> > but not when it's defined within the class.
>
> > 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, 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).
>
> > Anyway, the BDFL has the final word, and it looks like he's not going to
> > change anything here - but anyone is free to propose a PEP, isn't it ?
>
> The issue here has nothing to do with the inner workings of the Python
> interpreter. The issue is whether an arbitrary name such as "self"
> needs to be supplied by the programmer.
>
> Neither I nor the person to whom you replied to here (as far as I can
> tell) is suggesting that Python adopt the syntax of Java or C++, in
> which member data or functions can be accessed the same as local
> variables. Any suggestion otherwise is a red herring.
>
> All I am suggesting is that the programmer have the option of
> replacing "self.member" with simply ".member", since the word "self"
> is arbitrary and unnecessary. Otherwise, everything would work
> *EXACTLY* the same as it does now. This would be a shallow syntactical
> change with no effect on the inner workings of Python, but it could
> significantly unclutter code in many instances.
>
> The fact that you seem to think it would change the inner functioning
> of Python just shows that you don't understand the proposal.

It just occurred to me that Python could allow the ".member" access
regardless of the name supplied in the argument list:

class Whatever:

    def fun(self, cat):

        .cat = cat
        self.cat += 1

This allows the programmer to use ".cat" and "self.cat"
interchangeably. If the programmer intends to use only the ".cat"
form, the first argument becomes arbitrary. Allowing him to use an
empty argument or "." would simply tell the reader of the code that
the ".cat" form will be used exclusively.

When I write a function in which a data member will be used several
times, I usually do something like this:

    data = self.data

so I can avoid the clutter of repeated use of "self.data". If I could
just use ".data", I could avoid most of the clutter without the extra
line of code renaming the data member. A bonus is that it becomes
clearer at the point of usage that ".data" is member data rather than
a local variable.




More information about the Python-list mailing list