[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