Phil
Phil

Reputation: 14651

How can I call methods between two classes?

I have a class A. During the __init__ method of an instance of A;

I create these following two instances of classes B and C:

b = B()
c = C()

Once all's set, I need to call, within a method of B, a method from C.

Example:

Triggered:

b.call_c()

Does:

def call_c(self):
    parent.c.a_method_of_c()

What do I need to do to achieve this structure?

Upvotes: 1

Views: 575

Answers (3)

PaulMcG
PaulMcG

Reputation: 63719

Here is how this looks if you pass the A object to both B and C as a parent/container object:

class A(object):
    def __init__(self):
        self.b = B(self)
        self.c = C(self)

class B(object):
    def __init__(self, parent):
        self.parent = parent

    def call_c(self):
        self.parent.c.a_method_of_c()

class C(object):
    def __init__(self, parent):
        self.parent = parent

    # whatever...

Or, you can just pass the C instance to B's initializer like this:

class A(object):
    def __init__(self):
        self.c = C()
        self.b = B(self.c)

class B(object):
    def __init__(self, c):
        self.cobj = c

    def call_c(self):
        self.cobj.a_method_of_c()

class C(object):
    # whatever...

I like the second approach better, since it cuts out the dependencies of B and C on A, and the necessity of A to implement b and c attributes.

If B and C have to call methods on each other, you can still use A to make these associations, but keep B and C ignorant of A:

class A(object):
    def __init__(self):
        self.b = B()
        self.c = C()
        self.b.cobj = self.c
        self.c.bobj = self.b

class B(object):
    def __init__(self, c):
        self.cobj = None

    def call_c(self):
        if self.cobj is not None:
            self.cobj.a_method_of_c()
        else:
            raise Exception("B instance not fully initialized")

class C(object):
    # similar to B

In general, your goal is to try to avoid or at least minimize these dependencies - have a parent know about a child, but a child be ignorant of the parent. Or a container knows its contained objects, but the contained objects do not know their container. Once you add circular references (back references to a parent or container object), things can get ugly in all kinds of surprising ways. A relationship can get corrupted when one of the links gets cleared but not the reflecting link. Or garbage-collection in circular relations can get tricky (handled in Python itself, but may not be handled if these objects and relations are persisted or replicated in a framework).

Upvotes: 1

pepr
pepr

Reputation: 20762

I need to call, within a method of B, a method from C.

Basically, if the method is not a class method or a static method, then calling a method always means that you have access to the (c) object of the C class.

Have a look at the example:

#!python3

class B:
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return 'class B object with the value ' + str(self.value)    


class C:
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return 'class C object with the value ' + str(self.value)    


class A:
    def __init__(self, value):
        self.value = value
        self.b = B(value * 2)
        self.c = C(value * 3)

    def __str__(self):
        lst = ['class A object with the value ' + str(self.value),
               '  containing the ' + self.b.__str__(),
               '  containing also the ' + str(self.c),
               ]
        return '\n'.join(lst)


a = A(1)
print(a)
print(a.b)
print(a.c)

The self.b.__str__() is the example of calling the method of the object of the B class from the method of the object of the A class. The str(self.c) is the same, only called indirectly via the str() function.

The following is displayed:

class A object with the value 1
  containing the class B object with the value 2
  containing also the class C object with the value 3
class B object with the value 2
class C object with the value 3

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798666

You need to pass either of self or c to B() so that it can know about the other object.

Upvotes: 3

Related Questions