我有一些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 ]
我能想出的唯一解决方案是遍历{(1}}中每个类型的域(t1,t2),检查__subclasses__
是否为True给定的输入。
答案 0 :(得分:4)
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
,以便强烈谓词-sounding iscompatible
可以用来代替compatible_pred
命名的内容?
答案 1 :(得分:1)
如果您不需要并且依赖于异常处理,请不要检查类型 - 使用try
/ except
来捕获违反预期的实例。
在Python中,这是一种“懒惰类型”(但是强类型,更少让我感到沮丧的纯粹主义者)语言,反复调用isinstance
肯定会花费你的开销。在面对这样的设计问题时,我问自己的问题是“如果你不想让这个功能处理成对的自然,你为什么要跟它们一起打电话?”大概你正在做一些基于is_compatible的条件分支,我建议你把它改成条件调用。
看看你打算如何使用is_compatible的结果,可以得到更有针对性的答案。