【问题标题】:Creating a Java-like interface in Python在 Python 中创建类似 Java 的接口
【发布时间】:2013-10-13 23:49:30
【问题描述】:

我有多个具有共同功能的类,由于各种原因,它们的实现方式不同。我在相同的上下文中使用所有这些类,但直到运行时我才知道将使用哪一个。我想实例化不同的类,但使用相同的行代码来调用通用功能。

所以,我虽然使用继承(显然),现在我的代码看起来像这样:

class Base():
  def common(self):
    return "abstract"

class A(Base):
  def common(self):
    return "A"

class B(Base):
  def common(self):
    return "B"

我希望能够将任何派生类实例化为 Base(这样我就不必创建特殊情况并检查我添加的每个新类)并将其称为 common 方法并获得所需“A”或“B”结果。

【问题讨论】:

  • 您发布的代码有效吗?为什么或为什么不?
  • 用 Python 代替 Java!不要检查类型并完全取消您的基类。
  • 简而言之:duck-typing 使接口准过时。更长的答案:PEP-3119abstract base classes

标签: python inheritance interface


【解决方案1】:

Python 是一种带有鸭子类型的动态类型语言。与 Java 等静态类型语言不同,不需要接口。如果你有一个对象,你可以以任何你想要的方式调用它的 any 方法。解释器将尝试找到这样的方法并调用它,最糟糕的情况是您在运行时遇到异常。这就是动态类型语言的工作原理。

使用鸭子类型,只要在对象中拥有您想要的方法,您就可以期望该对象是您期望的类型。不需要检查它的继承性。

因此,在您的情况下,您甚至可以摆脱Base(除非您当然想提供默认实现)。然后你就得到一个对象,调用obj.common()。如果你想非常安全,你也可以先检查方法是否存在:

if hasattr(obj, 'common'):
    obj.common()

或者,如果您保留基本类型,也可以根据需要检查继承:

if isinstance(obj, Base):
    obj.common()

但通常,您只需调用该方法并检查它是否有效:它是easier to ask for forgiveness than permission。所以你会这样做:

try:
    obj.common()
except AttributeError:
    print('Oops, object wasn’t right after all')

【讨论】:

  • 如果保留基本类型,它应该是 ABC。
  • @delnan 好吧,我假设基本类型不仅仅是定义默认方法。
猜你喜欢
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
相关资源
最近更新 更多