【问题标题】:Python Type Checking & Inheritance IssuePython 类型检查和继承问题
【发布时间】:2010-05-19 16:24:41
【问题描述】:

我有一些依赖于类型检查的 Python 代码。我会尝试用数学语言表达我的问题,这样就很清楚了。我有几个类相互对应,形成一个继承链。

class Real(object):
    pass

class Integer(Real):
    pass

class Natural(Integer):
    pass

我有一个包含类型的元组。其中每一个都对应于某个函数的域。

t1 = ( Real, Real )
t2 = ( Real , Integer )

我想做某种形式的类型检查,如果元组中的每个坐标都是指定域的子类,则给定另一个元组( Natural , Natural )。例如对于某些功能getcompatibles 我想拥有:

getcompatibles( ( Real, Real ) ) = [ t1 ]
getcompatibles( ( Real, Integer ) ) = [ t1, t2 ]
getcompatibles( ( Natural, Natural ) ) = [ t1, t2 ]
getcompatibles( ( Natural, Real ) ) = [ t1 ]

我能想到的唯一解决方案是遍历每个 for domain (t1, t2) 遍历 __subclasses__ 中的每个类型,并检查 isinstance 对于给定输入是否为 True。

虽然效率极低,是否有更 Pythonic 的方式来做到这一点?

【问题讨论】:

  • 更改了 is_compatible -> getcompatibles

标签: python oop inheritance


【解决方案1】:
def compatible_pred(obj_types, fun_signature):
  if len(obj_types) != len(fun_signature): return False
  return all(issubclass(of, ft) for of, ft in zip(obj_types, fun_signature))

def is_compatible(obj_types, fun_signatures=(t1, t2)):
  return [t for t in fun_signatures if compatible_pred(obj_types, t)]

is_compatible 的名称对于 不是 谓词的东西来说确实非常令人困惑:为什么不给它起一个合理的名称,例如 getcompatibles,以便听起来像 @987654324 这样的强谓词@ 可以用来代替我必须命名的 compatible_pred

【讨论】:

    【解决方案2】:

    不要在不必要时检查类型,而是指望异常处理 - 使用 try / except 捕获违反预期的实例。

    在 Python 中,这是一种“惰性类型”(但是强类型,不太让纯粹主义者感到不安)语言,重复调用 isinstance 肯定会花费您的开销。面对这样的设计问题时,我问自己的问题是“如果你不希望这个函数处理成对的 Naturals,你为什么要用它们来调用它?”大概您正在执行某种基于 is_compatible 的条件分支,我建议您将其更改为条件调用。

    查看您打算如何使用 is_compatible 的结果可以得到更集中的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 2016-07-19
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多