Basic inheritance question

Bruno Desthuilliers bruno.42.desthuilliers at wtf.websiteburo.oops.com
Wed Jan 16 10:10:33 EST 2008


Lie a écrit :
> On Jan 15, 9:00 pm, Bruno Desthuilliers <bruno.
> 42.desthuilli... at wtf.websiteburo.oops.com> wrote:
>> Lie a écrit :
>>
>>
>>
>>> On Jan 7, 2:46 am, Bruno Desthuilliers
>>> <bdesth.quelquech... at free.quelquepart.fr> wrote:
>>>> Lie a écrit :
(snip)
>>>>> No, seriously it isn't Java habits only, most other languages wouldn't
>>>>> need explicit calling of class name.
>>>> Where is the "explicit calling of class name" exactly ?
 >>>
>>> Perhaps I was a bit tired when writing that (I wouldn't understand
>>> what I wrote if I were you)... what I meant is most other languages
>>> doesn't usually enforce us to explicitly state the containing class
>>> name, which in python is generally called "self".
 >>
>> 'self' (or whatever you name it) is not the "containing class name",
> 
> Current instance is what I meant, thanks for pointing out the
> incorrect term I used.
> 
>> it's the first argument of the function - which usually happens to be
>> the current instance when the function is used as a method.
> 
> And that's the point, self (or anything you name it) is almost always
> the current instance

# this is a plain function. In this function,
# 'obj' can be whatever that happens to have a (numeric)
# 'stuff' attribute
def func(obj, arg):
   return (obj.stuff + arg) / 2.0

# this is a class with an instance attribute 'stuff'
class Foo(object):
    def __init__(self, bar):
      self.stuff = bar + 42


# this is another (mostly unrelated) class
# with a class attribute 'stuff'
class Bar(object):
   stuff = 42


# this is a dummy container class:
class Dummy(object): pass


# now let's play:
import new

d = Dummy()
d.stuff = 84
print func(d, 1)

d.baaz = new.instancemethod(func, d, type(d))
print d.baaz(2)

f = Foo(33)
print func(f, 3)
Foo.baaz = func
f.baaz(4)

print func(Bar, 5)
Bar.baaz = classmethod(func)
Bar.baaz(6)


>  and that makes it functionally the same as Me and
> this in VB and Java.

Depends on the context, cf above !-)


>>> Most other languages
>>> 1) automatically assign the containing class' object
>> s/containing class' object/current instance/
>>
>>> in a keyword
>>> (Java: this, VB: Me) behind the screen,
 >
>> That's not very far from what a Python method object does -
>> automatically assign the current instance to something. The difference
>> is that Python uses functions to implement methods (instead of having
>> two distinct contructs), so the only reliable way to "inject" the
>> reference to the current instance is to pass it as an argument to the
>> function (instead of making it pop from pure air).
> 
> It isn't very far, but Python makes it obvious about the assignment
> (not behind the screen).

Exactly. And given both the simplicity of the solution and what it let 
you do, that's a *very* GoodThing(tm) IMHO.

(snip)

>>> and 2) automatically searches
>>> variable name in both the local variable table and the containing
>>> class variable table  (so to refer to a class variable named var from a
>>> method inside the class, we only need to write var, not self.var as in
>>> python).
>> This - as you know - cannot work well with Python's scoping rules and
>> dynamicity. Anyway, implicit object reference is definitively a
>> BadThing(tm) wrt/ readbility, specially with multiparadigm languages
>> (like Python or C++). Why do you think soooo many C++ shops impose the
>> m_something naming scheme ?
> 
> Implicit object reference for the containing class has little harm, if
> a class is so complex that there are more than 10 class-level
> variable, then it is obvious that that class needs to be fragmented to
> smaller classes.

Not necessarily. There are general rules (like 'keep your classes small 
and focused', which I wholefully agree with), there are guidelines (like 
'more than 10 member variables might smell like refactoring), and 
there's real life, where one very often faces classes that have much 
more than 10 member variables and still are as small and focused as 
possible.

> Remembering less than 10 variable and avoiding naming
> collision among just 10 variable is not hard (and 10 is really too
> many, most classes should only use 2-4 variables),

I really doubt you'll be able to write any working non-trivial software 
trying to strictly follow this rule.

> especially if you
> have a good IDE that employs Intellisense-like technology (IDLE has
> it).

IDLE is certainly not a "good IDE" in my book.

> And it is always a Bad Thing(tm) to use the same name for two
> variable in the class and in function (which is the main and only
> source of possible ambiguity) in ANY language, even in Python.

Ho, yes.... Like, this would be bad ?

class Person(object):
   def __init__(self, firstname, lastname, birthdate, gender):
     self.firstname = firstname
     self.lastname = lastname
     self.birthdate = birthdate
     self.gender = gender


C'mon, be serious. It's often hard enough to come with sensible names, 
why would one have to find synonyms too ? Try to come with something 
more readable than the above, and let us know. Seriously, this braindead 
rule about  "not using the same name for an attribute and a local var" 
obviously comes from languages where the "this" ref is optional, and 
FWIW it's obviously the wrong solution to a real problem (the good 
solution being, of course, to use the fully qualified name for 
attributes so there's no possible ambiguity).

>> Anyway, I actually know 3 languages (4 if C# works the same) that has
>> this implicit 'this' (or whatever the name) 'feature', and at least 5
>> that don't. So I'm not sure that the "most other languages" qualifier
>> really applies to point 2 !-)
> 
> What's this 5 languages? 

Smalltalk, Python, PHP, javascript, Ruby. I don't remember how Scheme, 
CLOS and OCaml handle the case.

> Are they a mainstream, high-level languages
> or lesser known, low-level languages? C-family, Java, and Basic are
> the Big Three of high-level programming language.

None of C, C++, Java nor Basic qualify as "hi-level". C is the lowest 
possible level above assembly, C++ is often refered to as an "object 
oriented assembler", Java is way too static, crippled, verbose an 
unexpressive to qualify as "hi-level" (even if it suffers from some 
problems usually associated with higher level languages). I won't even 
comment on basic (is that really a language at all ?).

>>> In VB, Me is extremely rarely used,
>> I used to systematically use it - like I've always systematically used
>> 'this' in C++  and Java.
> 
> And that is what reduces readability. A proficient VB/C/Java
> programmer 


There are quite a few proficient C/C++/Java programmers here. As far as 
I'm concerned, I would not pretend being one - I just have a good enough 
knowledge of C, Java and (alas) VB to be able to get up to speed in a 
reasonnable time frame.

As a side note, the problem just doesn't exists in C, which has 
absolutely no support for OO.

> would frown upon the extra, unneeded garbage as they
> thought it was clear already that the variable refers to a class-level
> variable. 

In C++, the canonical way to make this "clear" is to use the m_name 
convention. There must be some reason C++ programmers feel a need for 
this "extra, unneeded garbage" ?-)

> It is a different story if, like Python, the use of self is
> enforced by the language, the self wouldn't be viewed as extra
> unnecessary garbage.

>>> in Python, self is all
>>> over the place. Well, there is positive and negative to both sides,
>>> convenience in VB, and flexibility in Python.
>> As far as I'm concerned, there's *no* positive point in implicit object
>> reference, and there has never been (and before some paranoid nutcase
>> around accuse me of overzealous biggotry : I already held this very same
>> opinion years before I discovered Python).
> 
> There is one major positive point: convenience and shorter code.
> (isn't that two?)

These are not rated as "positive" in my book. That's perhaps why Python 
is so far MFL ?

> As I've pointed out, there is little harm in class-level variable's
> implicit reference.

Have some working experience on any non-trivial C++ project ?

>>> Compare the following codes:
>>> VB.NET:
>>> Public Class A
>>>     Dim var
>>>     Public Function aFunction()
>>>         return var
>> Add three levels of inheritence and a couple globals and you'll find out
>> that readability count !-)
> 
> It's the mental model that have to be adapted here, if the current
> class is inheriting from another class, you've got to think it as
> names from parent class as it is a native names, so you don't actually
> need to know where the variable comes from

In C++ (and VB IIRC), it might as well be a global So sorry but yes, I 
have to know where it comes from.

> since knowing where it
> comes from is breaking the encapsulation

Nope, it's knowing what you're doing and how the piece of software at 
hand is working. And FWIW, while data hiding is one possible mean of 
encapsulation, it's by no way a synonym for encapsulation.

> (which, in Python is very
> weakly implemented, which favors flexibility in many cases[1]).
> 
> [1] In Python, it is impossible to create a completely private
> variable, which is the reason why the mental model of these other
> languages doesn't fit Python.

Never heard about the infamous '#define private public' hack in C++ ? 
And don't worry, there are also ways to get at so called 'private' vars 
in Java.

>> In any non-trivial piece of C++ code, and unless the author either used
>> the explicit 'this' reference or the 'm_xxx' naming convention, you'll
>> have hard time figuring out where a given name comes from when browsing
>> a function's code.
> 
> If you're used to the implicit naming scheme it's easy to know where a
> variable came from, if not the current scope, it's the class' scope

You forgot the global scope.

(snip)

> As a final note:
> I don't think implicit class reference is superior to explicit class
> reference, neither do I think explicit class reference is superior to
> implicit class reference. I think both have their own +s and -s. I
> only pointed out that implicit do have its benefits,

"benefit" here is a judgement call. It happens that neither I nor 
probably most of the people here share your judgement on this. Time for 
you to "import this" I'd say.

> depending on the
> language used (obviously Python wouldn't benefit from using implicit
> behavior, due to it being extremely dynamic).

Not only. This is also (and almost firstly as far as I'm concerned) a 
matter of readability.

Anyway: this-dead-horse-been-beaten-to-hell-and-back... So if you 
*really* want to have the last word, I'll leave it to you !-)



More information about the Python-list mailing list