【问题标题】:super considered super, dependency injection via inheritance in python超级被认为是超级,通过python中的继承进行依赖注入
【发布时间】:2020-06-24 02:17:10
【问题描述】:

所以,我观看了 Raymond Hettinger 的演示super被认为是超级以及使用超级继承和多重继承利用依赖注入的能力https://youtu.be/EiOglTERPEo

在他的一个示例中,他向我们展示了他如何通过引入基类的模拟实现来模拟依赖项,并在新的子类实现中使用该模拟以提供可测试性:

class Robot(object):
   def left(self):
      print("walking left")
   def right(self):
      print("walking right")

class MyRobot(Robot):
   def clean(self):
      super().left()
      super().right()

现在,为了独立于 Robot 的实现来测试 MyRobot,根据他的介绍,应该提供 Robot 的模拟实现并在新的 Testable 类中使用它

class MockRobot(Robot):
   def left(self):
      print("mock left")
   def right(self):
      print("mock right")

class MyRobotTestable(MyRobot, MockRobot):
   pass

我了解方法解析顺序如何允许我们在新的可测试类中使用 MockRobot 的方法。

老实说,我不认为这是一个好的解决方案,因为我没有测试我的实际代码,除此之外我正在引入一个新的“类”,但仅用于使另一个类可测试的原因。

来自其他OOP语言:有什么理由不通过构造函数注入依赖吗?

即:

class MyRobot(object):
   def __init__(robot):
      self.robot = robot

   def clean(self):
      self.robot.left()
      self.robot.right()

我不需要任何额外的类来提供可测试性(除了模拟),我可以注入任何我想要的实现。

我认为这是遵循依赖倒置规则的正确 OOP。

【问题讨论】:

  • 如果你想继承多个实现相同功能的类怎么办?
  • 例如,Django 视图使用了很多“mixin”类,这些类覆盖了很多相同的方法。通过组合所有这些“mixins”,您可以获得一些非常复杂的行为和非常复杂的__mro__s,您的示例无法复制这些行为。下面是一个django rest框架的视图继承示例i.redd.it/ve66iak6gxm11.png
  • 感谢您指出这一点,我同意,mixin 在某些方面非常强大。我在问这是否是处理依赖注入和控制反转的正确方法。在我看来,可测试性将成为一件复杂的事情,如果有人按照建议引入一个新的假测试类,这不是我的实际测试类。我觉得违反了依赖倒置,知道一个接口的行为,而不是像这样处理它。

标签: python testing dependencies inversion-of-control super


【解决方案1】:

与经典依赖注入的不同之处在于实例化MyRobot 的主程序必须显式提供对Robot 类的依赖,并将其作为参数传递给构造函数。或者你可以创建一个提供依赖的工厂,主程序会调用这个工厂。

通过使用super() 进行依赖注入,对Robot 的依赖是透明的,但您仍然可以覆盖它以进行测试。我猜这是一种更 Pythonic 的依赖注入方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-29
    • 2014-07-21
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 2018-04-22
    • 2023-03-28
    • 2016-09-03
    相关资源
    最近更新 更多