Inheritance and name clashes
steve-REMOVE-THIS at cybersource.com.au
Tue Oct 5 03:29:19 CEST 2010
On Mon, 04 Oct 2010 09:51:18 -0700, Dennis Lee Bieber wrote:
> On 04 Oct 2010 05:08:20 GMT, Steven D'Aprano
> <steve-REMOVE-THIS at cybersource.com.au> declaimed the following in
>> from luncheon_meats import Ham
>> class Spam(Ham):
>> def __init__(self):
>> self.__x = "yummy"
>> You think you're safe, because the attribute __x is mangled to
>> _Spam__x. But little do you know, Ham itself inherits from another
>> class Meat, which inherits from Food, which inherits from
>> FoodLikeProducts, which inherits from... Spam. Which also has an __x
>> You now have a name clash.
> And you've just defined a circular inheritance tree -- I wouldn't
> expect ANY language to handle such... Presuming it doesn't choke on the
> parsing. Or a very confusing set of imports where you are
> re-using/re-defining a class name itself.
Er what? No, you've misunderstood me, I wasn't trying to imply that Spam
has *itself* as a base class. That would be ... interesting. No, what I
meant was that one of the base classes of Spam (probably in a different
module), happened to also be called Spam.
You don't even need different modules to demonstrate this:
>>> class Spam(object):
... __x = "spam"
... def test(self):
... assert self.__x == "spam"
>>> class Ham(Spam):
... __x = "ham"
Now accidentally add this:
>>> class Spam(Ham):
... __x = "spam spam spam"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in test
Of course if your module is so huge and confused that you don't know what
names you've already used, you have nobody but yourself to blame for
breakage like this.
But suppose you've just imported Ham from another module, and it inherits
from classes which come from some other library, which in turn inherit
from somewhere else, and so for to some arbitrary level of complexity.
How likely is it that you will know the *entire* inheritance tree from
top to bottom before deciding that it's safe to call your subclass Spam?
Of course in practice this is hardly ever a problem. Python tends to use
shallow inheritance trees where it is quite easy to be confident that the
name of your subclass is unique. Python also tends to encourage solutions
other than inheritance, such as delegation, composition, and functional
or procedural solutions that don't require a subclass at all.
Python encourages an attitude that protecting against accidental name
clashes like this is rarely worth it. It's not that name clashes can't
happen, but it's not worth the added complexity to have the language
protect against them. Ordinary testing and debugging techniques can solve
that problem when AND IF it occurs.
In my opinion, it's barely worthwhile to bother with double-underscore
names in the first place, let alone worth worrying about edge cases where
name mangling fails. I merely mentioned this to demonstrate that name
mangling is not a panacea.
(On the other hand, there are frameworks like Plone...
More information about the Python-list