Suppose I have a class A coming from a third-party library (FYI it is numpy.matrix). I want to expand its public interface with a wrapper class B.
class B(A):
def myMethod(self,arg):
return 'spam'
And also, I want to create B objects from A object. Since B will not hold any more attribute, I just really want to return the A object, with the B behavior:
class B(A):
def __new__(cls,a): # type(a)==A
return a.castTo(B) # pseudo-code
Is there a way to do it in python ?
Similarily, is there a way to cast B objects to A objects ?
Your class B's __new__ needs to call A's __new__. Here's a brief demo using the built-in list class.
class mylist(list):
def __new__(cls, obj=None):
return list.__new__(cls, obj)
def mymethod(self, msg):
print msg, id(self)
def main():
a = mylist('abc')
print a, id(a)
a.mymethod('hello')
if __name__ == '__main__':
main()
If you just want to add a simple function to an instance of an existing class, you can do this sort of thing.
class A(object):
pass
def silly(arg=None):
print 'This is silly', arg
b = A()
b.my = silly
b.my()
Note that b.my it just a function, not a method, so it does not get passed self when you call it. But you can pass it "by hand" by doing b.my(b)
Edit
As an alternative to writing list.__new__(cls, obj), you can call the super() function:
def __new__(cls, obj=None):
return super(mylist, cls).__new__(cls, obj)
But in most cases using the base class name is clearer and shorter. I guess there might be a reason to prefer super(), but I'm not enough of an expert on this stuff to say. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With