[Tutor] subclass problem: __names and type-checking

Brian van den Broek broek at cc.umanitoba.ca
Sat Oct 8 08:56:05 CEST 2005


Hi all,

I'm having an issue which resists my attempts to give a snappy label 
to it. I have a solution that doesn't feel entirely correct, and which 
I cannot actual apply to my original case.

The Issue:
I have a class which I want to subclass. The subclass adds some
additional arguments to __init__. I want both classes to run a sanity
check on their arguments before leaving their respective __init__
methods. I need both to do so, as the _BaseClass may be directly
instantiated. I need to ask permission for the arguments on instance
creation rather than for forgiveness later, as bad arguments passed to
__init__ could take many cpu cycles of other code before they
manifested themselves.

Here's a sketch of where I'm at:

class _BaseClass(object):

     def __init__(self, arg1, arg2):
         self.arg1 = arg1
         self.arg2 = arg2
         if type(self) == _BaseClass:
             # Problem (2) mentioned below shows up here.
             #
             # type test needed otherwise Subclass._validate_args
             # will be called before all subclass args processed by
             # SubClass.__init__, causing AttriuteError
             self._validate_args()

     def _validate_args(self):
         '''Performs sanity check on arguments'''
         if not type(self.arg1) in (int, long):
             raise TypeError
         # etc

class SubClass(_BaseClass):

     def __init__(self, arg1, arg2, arg3, arg4):
         super(SubClass, self).__init__(arg1, arg2)
         self.arg3 = arg3
         self.arg4 = arg4
         if type(self) == SubClass:
             # same reasoning as before -- leaving room for further
             # subclassing.
             self._validate_args()

     def _validate_args(self):
         super(SubClass, self)._validate_args()
         if not isinstance(self.arg3, basestring):
             raise TypeError
         # etc


This works as desired, but leaves two problems:

1) I suspect there may be a better way, as a) this doesn't feel quite 
right and b) in general with Python, it seems that if you are tempted 
to type test, you should rethink, and

2) I originally had __BaseClass rather than _BaseClass. But, with that 
naming, cannot figure out how to write the line

     if type(self) == __BaseClass:

so as to make it work. I know about the name mangling with __somename 
names, but I don't know how to manage it in this case.

The attempt of 4 lines up produces:

NameError: global name '_BaseClass__BaseClass' is not defined

This confuses me. I don't see why the error msg prepends '_BaseClass' 
as that name appears nowhere. That confusion aside, I've no idea how 
to effect what I want.

I think I won't want __BaseClass in the end, as I do expect it is 
possible that it will be instantiated directly, so the '__' seems 
inappropriate. But, the issue of how to do it remains.

So, details of '_' vs '__' aside, is my approach sound? And, how to 
deal with __BaseClass?


Best to all,

Brian vdB





More information about the Tutor mailing list