Inheritance and name clashes

Steven D'Aprano steve-REMOVE-THIS at cybersource.com.au
Mon Oct 4 21:29:19 EDT 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
> gmane.comp.python.general:
> 
> 
>> 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
>> attribute.
>> 
>> 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"
...
>>>
>>> Spam().test()
>>> Ham().test()
>>>


Now accidentally add this:


>>> class Spam(Ham):
...     __x = "spam spam spam"
...
>>> Ham().test()
>>> Spam().test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in test
AssertionError



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...
http://www.artima.com/weblogs/viewpost.jsp?thread=246341)



-- 
Steven



More information about the Python-list mailing list