0

A follow up from this question, which was not very well formulated. The answer provided some additional insight so now I have constructed a limited working example that explains it better.

Basically we have two subclasses A and B and a class C which inherits from both. Classes A and B both have a function MyFunc but which does different things.

I would like for class C to be able to use both functions and have full control of which function is called since I wish to do different things with each function. The comment in the limited working example below shows what I am trying to do.

    class A():
        def __init__(self, var1, var2):
            self.var1 = var1
            self.var2 = var2
        def MyFunc(self):
            result = self.var1 + self.var2
            return result
    
    class B():
        def __init__(self, var1):
            self.var1 = var1
        def MyFunc(self):
            result = self.var1**2
            return result
    
    class C(A,B):
        def __init__(self, var1, var2, var3):
            A.__init__(self, var1, var2)
            B.__init__(self, var3)
        def MyFunc(self):
            #in this function I want to call MyFunc from A and MyFunc from B. For example to add their results together

How can I call MyFunc in A and MyFunc in B from MyFunc in C?

Robert Christopher
  • 4,940
  • 1
  • 20
  • 21
user32882
  • 5,094
  • 5
  • 43
  • 82

2 Answers2

2

You can use name mangling to make attributes from a class available in a child class even if that child defines an attribute with the same name.

class A():
    def __init__(self, var1, var2):
        self.var1 = var1
        self.var2 = var2
    def __MyFunc(self):
        result = self.var1 + self.var2
        return result
    MyFunc = __MyFunc

class B():
    def __init__(self, var1):
        self.var1 = var1
    def __MyFunc(self):
        result = self.var1**2
        return result
    MyFunc = __MyFunc

class C(A,B):
    def __init__(self, var1, var2, var3):
        A.__init__(self, var1, var2)
        B.__init__(self, var3)
    def MyFunc(self):
        return self._A__MyFunc() + self._B__MyFunc()

c = C(1, 2, 3)
print(c.MyFunc())
# 14
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
  • Looks good but why on earth is the result 14? Should it not be 12? 1+2+3**2 = 12 – user32882 Mar 16 '18 at 16:22
  • `c` has two var attributes `var1` and `var2`. `var1` is `3` and `var2` is `2`. Can you see why? – Patrick Haugh Mar 16 '18 at 16:24
  • Not really.... I thought the __init__ method for C should take care of that and give `c` var1 = 1, var2 = 2 and var3 = 3. What am I missing here? – user32882 Mar 16 '18 at 16:26
  • None of your classes define a `self.var3`. So `C` gets `var1` and `var2` from `A`. It then gets `var1` from `B`, which overwrites the `var1` it got from `A`. This is one of the reasons it's important to give things descriptive names. – Patrick Haugh Mar 16 '18 at 16:28
  • What does `A.__init__(self, var1, var2)` do in that case? Does it pass the class `C` into `A`? I'm very confused – user32882 Mar 16 '18 at 16:33
  • It sets `c.var1 = 1` and `c.var2 = 2`. But then you call `B.__init__(self, var3)`, which sets `c.var1 = 3`. – Patrick Haugh Mar 16 '18 at 17:24
  • I think I get it now. At the level of `C` it still sees `self.var1` as the same variable. It is not 'local' to `B`. Well thats exactly what I need. I need it to stay local. Should I name mangle the variables as well? Is that even possible?\ – user32882 Mar 20 '18 at 19:29
0

I tried to make the solution look as simple as possible using your example suggestion.

    def MyFunc(self):
        result = 0
        result += A.MyFunc(self=self)
        result += B.MyFunc(self=self)
        return result
SebaLenny
  • 46
  • 2