Attack a sacred Python Cow

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Mon Jul 28 07:23:56 EDT 2008


Russ P. a écrit :
> 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

Python has nothing like "data member" (nor "member function" etc). It 
has class attributes and instance attributes, period. *Python is not 
C++*. So please stop using C++ terms which have nothing to do with 
Python's object model.

> 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.

The main reason to alias an attribute is to avoid the overhead of 
attribute lookup.

> A bonus is that it becomes
> clearer at the point of usage that ".data" is member data rather than
> a local variable.

I totally disagree. The dot character is less obvious than the 'self.' 
sequence, so your proposition is bad at least wrt/ readability (it's 
IMHO bad for other reasons too but I won't continue beating that poor 
dead horse...)




More information about the Python-list mailing list