组成OOP

时间:2016-03-19 10:38:31

标签: python oop

我有一个A级,它严格意义上包含了一个' has-a'关系I.e. A包含B是有意义的。但是B上只有几个特定的​​方法调用会影响A.在大多数情况下,建模这只会导致A类的方法调用B类的方法。没有真正的好处和两个函数调用的缺点。

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)

人们在A中提供方法的想法是什么,当它改变B时需要特别需要。但是否则直接去B:

z=A()
z.addToB(a)
z.b.methSpecificToB(x,y,z)

我觉得我打破封装有点做这件事,但它更有意义而不是简单地提供多余的方法..

2 个答案:

答案 0 :(得分:1)

我通常更喜欢在A上调用方法的间接调用B上的方法,因为它可以保护A客户端免受A和B实现中的更改。例如,如果以后需要更改则需要调用了closeSpecificToB和B上的其他方法,我只需要更改A.addtoB,而如果Z和其他类直接调用B,则必须更改它们。

最终取决于B改变的可能性。如果这种情况永远不会发生,那么暴露B可能没问题,但如果它有可能那么间接更安全。

答案 1 :(得分:0)

我会用@property装饰器来解决这个问题。设置A.B后,系统会自动设置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

这里发生的是,当您设置foo.b时,它会保存为foo._b。 (下划线表示通常用于内部使用的'隐藏'变量。)同时,bar.a设置为foo,使您可以从{{1}访问foo }}

尝试访问bar时,会返回foo.b。由于我们之前已将其设置为foo._b,因此我们还会从bar访问bar

Python属性有很多教程。 This one是好的。