Kent Johnson said unto the world upon 2005-10-08 07:08: > Brian van den Broek wrote:
<snip problem spec of wanting a class and its subclass to each call a sanity-check on the arguments to __init__ from within the __init__> >> >>Here's a sketch of where I'm at: <code below trimmed for repost> >>class _BaseClass(object): >> >> def __init__(self, arg1, arg2): >> self.arg1 = arg1 >> self.arg2 = arg2 >> if type(self) == _BaseClass: >> self._validate_args() >> >> def _validate_args(self): >> if not type(self.arg1) in (int, long): >> raise TypeError >> >>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: >> self._validate_args() >> >> def _validate_args(self): >> super(SubClass, self)._validate_args() >> if not isinstance(self.arg3, basestring): >> raise TypeError >> >> >>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 Thanks for the reply, Kent. > I can think of two alternatives: <snip alternative which is clear to me, leaving:> > - Have two validate functions in each class - the shared _validate_args() and a class-specific _validate_SubClassArgs(). Call the class-specific version from __init__() and the shared one from other clients. Then you would have > > class _BaseClass(object): > def __init__(self): > ... > self._validate_BaseClass() > > def _validate_args(self): > super(_BaseClass, self)._validate_args() > self._validate_BaseClass() > > and similar code in SubClass. I think I see the idea. But I take it you didn't mean to have: > def _validate_args(self): > super(_BaseClass, self)._validate_args() within a method of _BaseClass (a subclass of object), as that will produce: AttributeError: 'super' object has no attribute '_validate_args' >>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. > > > The __ name only gets mangled inside the class definition. The > class name itself is not getting mangled. From the language > reference: > > Private name mangling: When an identifier that textually occurs in > a class definition begins with two or more underscore characters > and does not end in two or more underscores, it is considered a > private name of that class. Private names are transformed to a > longer form before code is generated for them. OK, thanks. But I'm still not quite there. Consider this example code: class _OneUnderBase(object): def __init__(self): if type(self) == _OneUnderBase: print "From _OneUnderBase" else: print "From subclass", class __TwoUnderBase(object): def __init__(self): if type(self) == __TwoUnderBase: # What to write here print "From __TwoUnderBase" else: print "From subclass", class Sub1(_OneUnderBase): def __init__(self): super(Sub1, self).__init__() print "Sub1" class Sub2(__TwoUnderBase): def __init__(self): super(Sub2, self).__init__() print "Sub2" s1 = Sub1() s2 = Sub2() When run, this gives: From subclass Sub1 Traceback (most recent call last): File "C:/Python24/foofoofoo.py", line 26, in -toplevel- s2 = Sub2() File "C:/Python24/foofoofoo.py", line 22, in __init__ super(Sub2, self).__init__() File "C:/Python24/foofoofoo.py", line 10, in __init__ if type(self) == __TwoUnderBase: # What to write here NameError: global name '_TwoUnderBase__TwoUnderBase' is not defined >>> What should I write in the if test of __TwoUnderBase.__init__() to make it work? (Nevermind the desired behaviour here could be obtained without the type test. How to work that test is the point I'm interested in.) Thanks, Brian vdB _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor