【问题标题】:Pythonic way to add several methods to several classes?向多个类添加多个方法的 Pythonic 方式?
【发布时间】:2012-10-10 13:42:51
【问题描述】:

将多个相同的方法添加到多个类中最 Pythonic 的方法是什么?


我可以使用类装饰器,但这似乎带来了相当多的复杂性,并且比其他方法更难读写。

我可以创建一个包含所有方法的基类,并让其他类继承,但是对于某些类,我会很想允许多重继承,我经常读到的应该避免或最小化。此外,“is-a”关系也不适用。

我还可以将它们从方法更改为使它们成为独立函数,这些函数只期望它们的值通过鸭子类型提供适当的属性。这在某些方面是干净的,但它不是面向对象的,并且在何时可以在该类型的对象上使用函数时不太清楚。

我可以使用委托,但这要求所有想要调用的类都有调用辅助类方法的方法。这将使代码库比其他选项长得多,并且每次我想向助手类添加新函数时都需要添加一个委托方法。

我知道在某些情况下,将另一个类的实例作为属性很好地工作,但它并不总是干净利落,并且会使调用变得比其他情况更复杂。

玩了一会儿之后,我倾向于继承,即使它导致多重继承。但我犹豫了,因为有大量文本强烈警告不要允许多重继承,有些(例如wikipedia 条目)甚至说应该尽量减少仅用于代码重用的继承。


举个例子可能会更清楚,所以举个简单的例子,假设我们正在处理许多不同的类,它们都在 x、y 网格上都有一个位置。有很多操作我们可能希望为具有 x、y 位置的所有事物创建方法,例如获取两个此类实体之间的距离、或者它们之间的相对方向、中点等的方法。

让所有此类类访问这些仅依赖于将 x 和 y 作为属性的方法的最 Pythonic 方式是什么?

【问题讨论】:

    标签: python inheritance styles decorator


    【解决方案1】:

    对于您的具体示例,我会尝试利用鸭式打字。编写简单的函数,接收假定具有xy 属性的对象:

    def distance(a, b):
        """ 
        Returns distance between `a` and `b`.
        `a` and `b` should have `x` and `y` attributes.
        """
    
        return math.sqrt((a.x-b.x)**2 + (a.y-b.y)**2)
    

    非常简单。为了明确如何使用该函数,只需将其记录下来即可。

    【讨论】:

    • 谢谢。看来这可能是要走的路。
    【解决方案2】:

    简单的旧函数最适合这个问题。例如。而不是这个...

    class BaseGeoObject:
    
      def distanceFromZeroZero(self):
        return math.sqrt(self.x()**2 + self.y()**2)
      ...
    

    ...只有这样的功能:

    def distanceFromZeroZero(point):
      return math.sqrt(point.x()**2 + point.y()**2)
    

    这是一个很好的解决方案,因为它也很容易测试 - 不必为了执行特定功能而进行子类化。

    【讨论】:

      猜你喜欢
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-16
      • 2017-04-27
      • 2023-03-26
      相关资源
      最近更新 更多