Name conflict in class hierarchy

Larry Bates larry.bates at websafe.com
Sat May 20 18:30:12 EDT 2006


Jeffrey Barish wrote:
> I believe that the answer to my question is no, but I want to be sure that I
> understand this issue correctly:  Suppose that there are two classes
> defined as follows:
> 
> class A(object):
>     def f1(self):
>         print 'In A.f1, calling func'
>         self.func()
> 
>     def func(self):
>         print 'In A.func'
> 
> class B(A):
>     def func(self):
>         print 'In B.func, calling A.f1'
>         A.f1(self)
> 
> Class A was defined by someone else or it comes from a library, so I have no
> prior information about what is in it.  I subclass A to add some new
> functionality, and I call the new function "func".  The function B.func
> uses A.f1, but unbeknownst to me, A.f1 uses A.func.  Unfortunately, class B
> overrides func, so the call in A.f1 to self.func actually invokes B.func,
> resulting in this case in an infinite loop.  Is there a way from B to
> specify that A should use its own version of func and ignore the version in
> B?  I know that I could rename A.func to avoid the name clash, but since A
> is actually in a library, I will lose that change when I upgrade the
> library.  I could rename B.func, but there is already a bunch of code that
> calls it so I would have to update all the calls.  That seems like the
> correct solution, though.  The other possibility is to use composition
> rather than subclassing:
> 
> class B:
>     def func(self):
>         print 'In B.func, calling A.f1'
>         a = A()
>         a.f1()
> 
> but then B does not inherit other functions of A that I would like to use. 
> It struck me that this must be a common problem in OOP, so I'm wondering
> whether there is a simple solution that I am missing.

When you subclass an object it is your responsibility to check to make sure
you don't override existing methods in that class unintentionally.  Of course
you may want to intentionally override the methods so as to replace them with
your own methods.  You are correct, renaming A.func wouldn't be a good idea.
A good editor should make changing all the calls to B.func not be all that
hard.

You can easily get information about the methods by doing an import and dir().

Example:

>>> import ConfigParser
>>> dir(ConfigParser)
['ConfigParser', 'DEFAULTSECT', 'DuplicateSectionError', 'Error',
'InterpolationDepthError', 'InterpolationError',
'InterpolationMissingOptionError', 'InterpolationSyntaxError',
'MAX_INTERPOLATION_DEPTH', 'MissingSectionHeaderError', 'NoOptionError',
'NoSectionError', 'ParsingError', 'RawConfigParser', 'SafeConfigParser',
'__all__', '__builtins__', '__doc__', '__file__', '__name__', 're']


Depending on the author, you may also be able to get extensive help
on all the methods with help().

>>> help(ConfigParser)
Help on module ConfigParser:

NAME
    ConfigParser - Configuration file parser.

FILE
    c:\python24\lib\configparser.py

DESCRIPTION
    A setup file consists of sections, lead by a "[section]" header,
    and followed by "name: value" entries, with continuations and such in
    the style of RFC 822.


-Larry Bates



More information about the Python-list mailing list