0

New to python here and I am looking to attach some class, ClassA.methodA to another ClassB as below

def methodA(self, x=None, y=None, z='somevalue', l=None, m=False, **kwds):

  ... Some logic here....

  a = self.getMyInstanceOfClassA() //a is of type ClassA, not ClassB
  a.methodA(x,y,z,l,m,**kwds) 

ClassB.methodA = methodA

...

h = ClassB()
h.methodA("p1", "p2", m=True)

The goal is to keep the signature of ClassB.methodA the same as it is supposed to be on the actual ClassA.methodA which is accessible on ClassB.getMyInstanceOfClassA() method.

The reason I am doing this is to avoid my user to write this code

h = ClassB()
---the extra logic---
a = h.getMyInstanceOfClassA()
a.methodA(....)

an instead just say

h = ClassB()
h.methodA(....)

and I embed the extra logic inside the new methodA on ClassB.

methodA is something meaningful in our domain and I have to keep its name and exact signature

I have to import both ClassA and ClassB from our internal libs and I can't make ClassB inherit from ClassA.

The point is that methodA is usually not called with all of its arguments and the arguments passed depends on what you want methodA to do. This h.methodA("p1", "p2", m=True) fails with some error complaining about passing too many argument to it.

Am I wrapping the methodA correctly?

iCode
  • 4,308
  • 10
  • 44
  • 77
  • Can you give a complete example of what you are using (a small complete one that works on our machine) and the complete traceback? – Anand S Kumar Aug 23 '15 at 04:10
  • And what does - `a = self.embededClass()` give? When you do `MyClass.methodA = methodA` you are overriding this new function at the class level, not just for your instances, so if there was a previous function, unless you saved it somewhere, you would not be able to get that back. – Anand S Kumar Aug 23 '15 at 04:13
  • It is the company code so harder to share but I update the question with more info. Hopefully it more clear now. – iCode Aug 23 '15 at 04:15
  • on a = self.embededClass(), a is a different type of some other libs we have and has no knowledge of MyClass. I also intend to have MyClass.methodA = methodA overriding this new function at the class level, not just an instance. – iCode Aug 23 '15 at 04:16
  • Well can't you have a different name for the function that is wrapping methodA ? – Anand S Kumar Aug 23 '15 at 04:18
  • I update the question with your answer. Sorry if I am not explaining myself clear enough. – iCode Aug 23 '15 at 04:25
  • You still aren't showing the actual failing code, or the actual failure. – Patrick Maupin Aug 23 '15 at 04:27
  • Why do you call `classB.methodA` from the client code with less parameters than in signature? And what `ClassB.methodA = methodA` is for? It all is a little messy, you know. – Mikhail Batcer Aug 23 '15 at 05:10
  • Sorry about that. It is because how classA.methodA is. You do not have pass all the parameters. I assume this with any other python method and the defaults are used for the parameters not passed I assume. Isn't this common in python? I am new to python see please kindly correct if I am looking at this incorrectly. – iCode Aug 23 '15 at 09:09
  • ClassB.methodA = methodA is to attach the my newly created methdA to ClassB. – iCode Aug 23 '15 at 09:24

2 Answers2

0

I think you would typically just use inheritance or just make that method a function unrelated to the class with one of the inputs being the instance of that class. Or you would just wrap it in a lambda function.

Python: Bind an Unbound Method?

If however you want to take a method and bind it to an instance of a class use something like the below code.

inst = MyClass()
inst.methodA = methodA.__get__(inst, MyClass)
Community
  • 1
  • 1
justengel
  • 6,132
  • 4
  • 26
  • 42
  • No, I want this across all instances of MyClass. Inheritance is not an option because I have no control over embededClass() existence.. think of it as I do have access to the MyClass code either. – iCode Aug 23 '15 at 04:31
0

I am not sure what is causing your error (We cannot be sure unless you atleast show the complete traceback or atleast a demo code that reproduces your issue).

But from the code that you have pasted, what you are trying to do would not be possible. Lets take a simple example -

>>> class A:
...     def methodA(self, a):
...             print(a)
...             print("In A")
...
>>> def methodA(self, a, b=None):
...     print("In Main")
...     if b == None:
...             return
...     else:
...             h = type(self)
...             h.methodA(self, a)
...
>>> A.methodA = methodA
>>> h = A()
>>> h.methodA(1,2)
In Main
In Main

I just put the b == None part, so that the code does not do inifinite recursion, but what you are trying to would cause infinite recursion. Why?

Because you have changed methodA to point to a new method at the class level, so even if you call methodA for the class, it would still call the newly bound methodA , not the old one.

If you really do not want the users to call the old methodA directly, one thing you can do is to bind that method to a different name , maybe _methodA , and then bind your new function to methodA. Example -

>>> class A:
...     def _methodA(self, a):
...              print(a)
...              print("In A")
...
>>> def methodA(self, a, b=None):
...     print("In Main")
...     if b == None:
...             return
...     else:
...             h = type(self)
...             h._methodA(self, a)
...
>>> A.methodA = methodA
>>> h = A()
>>> h.methodA(1,2)
In Main
1
In A
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
  • So sorry for the confusion. methodA is on a different class and not ClassA. I am going to update the question shortly. Sorry again. – iCode Aug 23 '15 at 04:39
  • Like I said, untill you give an exact demo that reproduces your issue along with the complete traceback, we would not be able to help you. – Anand S Kumar Aug 23 '15 at 04:41
  • Sure, I updated the question and hopefully more clear now. I totally understand but I can't publish the real ClassA and ClassB. I will try to reproduce this with public code. Could you at least check if the param passing makes sense? – iCode Aug 23 '15 at 04:56
  • Can you atleast show the traceback you are getting? the code seems like it should work, but if it isn't then we need the traceback to find that out. – Anand S Kumar Aug 23 '15 at 05:00