[Tutor] Class decorator on a derived class not initialising the base classes using super - TypeError
Peter Otten
__peter__ at web.de
Mon Feb 24 18:23:26 CET 2014
Sangeeth Saravanaraj wrote:
> I am trying to capture an object initiation and deletion events using the
> __call__() and __del__() methods with the following approach.
Note that there is no guarantee that __dell__ will ever be called. Usually
it is better to introduce a weakref with callback.
> class A(object):
> def __init__(self, klass):
> print "A::__init__()"
> self._klass = klass
>
> def __call__(self):
> print "A::__call__()"
> return self._klass()
>
> def __del__(self):
> print "A::__del__()"
>
> class Parent1(object):
> def __init__(self):
> print "Parent1:: __init__()"
> super(Parent1, self).__init__()
>
> class Parent2(object):
> def __init__(self):
> print "Parent2:: __init__()"
> super(Parent2, self).__init__()
>
> @A
> class B(Parent1, Parent2):
> def __init__(self):
> print "B::__init__()"
> super(B, self).__init__()
>
> def main():
> b = B()
>
> if __name__ == "__main__":
> main()
>
>
> I decorate a class, say class B (whose object initiation and deletion I
> wanted to capture) with a decorator class A. Please note that the class B
> is derived from two classes - Parent1 & Parent2 and I want to use super()
> method to initialise the parent classes.
>
> When I executed the above code snippet, I ran into the following issue:
>
>
> A::__init__()
> A::__call__()
> B::__init__()
> Traceback (most recent call last):
> File "so.py", line 40, in <module>
> main()
> File "so.py", line 36, in main
> b = B()
> File "so.py", line 10, in __call__
> return self._klass()
> File "so.py", line 32, in __init__
> super(B, self).__init__()
> TypeError: must be type, not A
> A::__del__()
>
>
> When I commented "super(B, self).__init__()" in the class B :: __init__()
> method, it returned an object of type B and I was able to see the prints
> in the __call__ and __del__ methods but the __init__() methods of the base
> classes (Parent1 & Parent2) are not called!
>
> From the error message, what I could understand is - the object returned
> by A::__call__() is not of type B but of type A. But when I put a print in
> the A::__call__() I could see it returns an object of type B and not A.
>
> Now the question is - With this approach to capture the initiation and
> deletion events of an object, how do I initialise the base classes using
> super()?
You'd have to introduce a naming convention or rewrite your class to be
aware of the wrapping in some way:
@A
class B(Parent1, Parent2):
def __init__(self):
print "B::__init__()"
super(B._klass, self).__init__()
Not pretty.
> Or, is there any other better way to capture the __call__ and __del__
> events for an object of a certain class - if so, how?!
Most certainly, but you have to give some details about what you are up to
first.
> PS:
> http://stackoverflow.com/questions/21826854/typeerror-when-using-super-
method-with-class-decorator-for-a-derived-class
More information about the Tutor
mailing list