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

Reply via email to