Reputation: 1452
I have a class A that contains Class B in a strict sense of a 'has-a' relationship I.e. It makes sense for A to contain B. However there are only a couple of specific methods calls on B will affect A. For the most part modelling this will just lead to Class A having a method that calls Class B's methods with no real benefit and the downside of two function calls.
class A():
b=B()
__init__(self):
self.a=[]
def addToA(self,a):
self.a.append(a)
def addToB(a):
# do something with self.a
b.addToB(a)
What are people's thoughts on providing methods within A that is needed specifically when it alters B. however going to B directly otherwise:
z=A()
z.addToB(a)
z.b.methSpecificToB(x,y,z)
I feel I'm i'm breaking the encapsulation a little doing this however it makes more sense rather than simply providing superfluous methods..
Upvotes: 0
Views: 86
Reputation: 3301
I would solve this with a @property
decorator. When you set A.B
, this will automatically set B.A
.
class A:
_b = None
@property
def b(self):
return self._b
@b.setter
def b(self, b):
self._b = b
b.a = self
class B:
a = None
foo = A()
bar = B()
foo.b = bar
bar.a == foo # True
foo.b == bar # True
What happens here is that when you set foo.b
, it is saved as foo._b
. (The underscore indicates a 'hidden' variable that is generally used for internal usage.) At the same time, bar.a
is set to foo
, enabling you to access foo
from bar
.
When trying to access foo.b
, foo._b
is returned instead. Since we set that to bar
earlier, we also access bar
from foo
.
There are many tutorials on the Python properties. This one is kind'a OK.
Upvotes: 0
Reputation: 55630
I'd generally prefer the indirection of calling the method on A to call the method on B because it protects A's clients from changes in the implementation of A and B. For example, if later changes require that methodSpecificToB and some other method on B are called, I need only change A.addtoB, whereas if Z and other classes call B directly they all must be changed.
Ultimately it depends on the likelihood of B changing. If that's never going to happen then exposing B is probably ok, but if it's a possibility then indirection is safer.
Upvotes: 1