2

I have a class:

class A():
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def method_A(self):
        return self.a

Now, I have another class B:

class B():

    def __init__(self, c,d):
        self.c = c
        self.d = d

    def method_B(self):
        # do computations with a and b from class A
        # return A.a * c

One solution is to have B inherit from A but that means that it inherits all attributes of A which is something that I don't want.

For example it will be :

class B(A):
    def __init__(self,a,b,c,d)
        A().__init__(self,a,b)
        self.c = c
        self.d = d

So, I have to initialize my B class with def __init__(self,a,b,c,d) all arguments (from A and for B) , right?

Is there a way I can avoid that ?And still have access to class A attributes and methods?

---------- UPDATE 1 --------------------------------------

Updated according to the answers.

I want to be able to use an array of class A as input to class B.

I tried:

import numpy as np

class B():

    def __init__(self, c, d, the_a):
        self.c = c
        self.d = d
        self.the_a = the_a


    def method_B(self):
         for i in self.the_a:
            return self.the_a[0][0].a * self.c

a = np.array([[A(2, 4), A(3,5)]])
b = B(4, 4, a)
print(b.method_B())

and I am receiving : the value 8 .

But obvious I am not correctly using the loop in method_B.

I am using only the 0 index, but I can't figure!

------- UPDATE 2 ------------------------------

I am almost there..

 def method_B(self):
     for idx, x in np.ndenumerate(self.the_a):

        self.the_a[idx].a = self.the_a[idx].a * self.c
        self.the_a[idx].b = self.the_a[idx].b * self.c

    return self.the_a

Now, it returns me [[<__main__.A object at 0x7f165426c9b0> <__main__.A object at 0x7f165426c898>]] .

Is there a way I can receive the updated array like:

np.array([[ A(8, 16), A(12,20)]])
George
  • 5,808
  • 15
  • 83
  • 160
  • If you want to initialise an instance of `A` in `B` you're going to have to pass the arguments one way or another – Moses Koledoye Feb 01 '17 at 10:05
  • You've given b a numpy array of `A` instances, do you want `B` to have multiple `A`? If not then just give `B` a single `A` instance instead of a list of them. Otherwise your `B.__init__` needs to handle multiple `A` instances. – Steven Summers Feb 01 '17 at 11:10
  • @StevenSummers:yes, I want B to have as input an array of A instances. – George Feb 01 '17 at 11:11
  • `self.the_aV1 = the_a.a` and `self.the_aV2 = the_a.b` isn't going to work as `the_a` is a numpy array which as the error message states doesn't have an attribute `a`. What do you want `the_aV1` and `the_aV2` to be since you want multiple `A`? – Steven Summers Feb 01 '17 at 11:14
  • @StevenSummers:the a and b are the values of the A class.So, i want to extract these values from the input array.So, regarding a values , I have : 2 and 3.regarding b values , i have : 4 and 5.And I want to make calculations based on these values ( as in the method_B) – George Feb 01 '17 at 11:16
  • I'd recommend using a list instead of an array, `a = [A(2, 4), A(3,5)]`. It'll be easier to iterate over that. And with content like `class A`, you can't do any array math of the array form of `a`. – hpaulj Feb 01 '17 at 17:09
  • @hpaulj:But numpy arrays are more effective in terms of memory consumption and speed.Because , I may use thousand of lines of this array. – George Feb 01 '17 at 17:11
  • In update 1 you were returning from the loop too early; instead you should collect values from all the loops and return that. In the second update you appear to correctly update values in `a`. But the method itself returns `None` - because there isn't a `return` statement. I think you should focus on making `method_B` work right as a standalone function. Once that works you can turn it into a method. – hpaulj Feb 01 '17 at 17:13
  • Arrays like yours, with `dtype=object` are not more efficient. They just contain pointers to your `A` objects, just as lists do. The fact that you have to iterate on `a` to perform this simple multiplication proves that the array form doesn't help. The only thing it adds is the multidimensional shape. – hpaulj Feb 01 '17 at 17:14
  • @hpaulj, I agree. Your function doesn't return anything, hence it's return value is none. If your functions returned what you wanted to use, then the statement could work. So the_a would have to return something you want. – Nick H Feb 01 '17 at 17:57
  • @NickHale:I have updated my post (update 2).I want to return the whole array and not the object. – George Feb 02 '17 at 11:01
  • It's tricky to replicate, but my first thought is 'return list(self.the_a)' Then you can convert that list to an array if you need to. Perhaps try the multiplication operation in a list comprehension. That may stop it giving you an array of objects. – Nick H Feb 02 '17 at 12:20

3 Answers3

2

You need an instance of A:

def method_B(self, the_a):
    return the_a.a * self.c
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • But how can i initialize the A instance?Don't I have to use the init parameters of A in the B class?Can you give me a more complete example please? – George Feb 01 '17 at 10:09
2

Hold an instance of class A in class B.

class A():
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def method_A(self):
        return self.a

class B():

    def __init__(self, c, d, the_a):
        self.c = c
        self.d = d
        self.the_a = the_a

    def method_B(self):
        return self.the_a.a * self.c

a = A(1, 2)
b = B(3, 4, a)
Tobi S.
  • 183
  • 8
  • And if I have many instances that I want to supply to B ?If I have an array(numpy) or list of A instances? – George Feb 01 '17 at 10:37
  • Instead of only one instance of A, you can pass a list with instances of A. In your method_B you can iterate over it and do whatever you nedd to do. – Tobi S. Feb 01 '17 at 10:47
  • Can you please give me an example?because , I am using something like : `a = np.array([[A(2, 4), A(3,5)]])` and a loop in method_B but I have an error about accessing the attribute from class B init. – George Feb 01 '17 at 10:49
2

To follow on the previous answer, if you create an instance of A:

a = A(a, b)

then, in class B, you can pass in that instance as a single argument and access any method(or variable for that matter) by referring to it's instance:

class B():
    def __init__(self, c, d, instance_of_a):
    self.c = c
    self.f = d
    self.e = instance_of_a.[the method or variable you want from class A]

Hope this helps,

Nick H
  • 1,081
  • 8
  • 13
  • And if I have many instances that I want to supply to B ?If I have an array(numpy) or list of A instances? – George Feb 01 '17 at 10:37
  • Ok, a list would of objects would be the way I would go here: [link](http://stackoverflow.com/questions/3182183/creating-a-list-of-objects-in-python) I don't think numpy can handle a list of objects. – Nick H Feb 01 '17 at 11:12