我真的希望这不是重复。我试图搜索我的问题,但我似乎无法找到它。
所以我有一个相当简单的功能,可以将脚转换为米:
def feetToMeters(val):
return numpy.array(val) * 0.3048
这很好用,并接受整数,浮点数,数组和列表。但是,如果我放入一个列表(而不是一个numpy数组),我想要返回一个列表。所以我写了这个:
def feetToMeters(val):
try:
return val * 0.3084
except TypeError:
return [0.3084 * v for v in val]
(或者我可以使用return list(numpy.array(val) * 0.3084)
作为最后一行,如果我想在这里使用numpy
,我不知道这是否真的重要。)
这是在这里加入duck-typing的最佳方法,这样我就可以避免使用type
函数了吗?最初我试过AttributeError
,但它没有用。尽管如此,我仍对TypeError
感到厌倦,尽管它似乎有效。
使用if type(val) is list
代替是否是亵渎神灵?
答案 0 :(得分:6)
使用
if type(val) is list
代替是否是亵渎神灵?
是的,因为它不适用于列表的子类。如果你想这样,至少做isinstance(val, list)
。这是一个专门处理列表的解决方案,并将其他所有内容(包括标量和元组)转换为NumPy数组:
def feetToMeters(feet):
meters = np.asarray(feet) * 0.3048
return list(meters) if isinstance(feet, list) else meters
请注意:
list
子类的实例将导致返回普通list
; 您可以对此进行扩展以特别处理更多类型,但通常,对于要处理的每种类型,您需要编写更多代码,因为您需要知道如何构造该类型。因此,这种类型转换通常留给客户端代码。
答案 1 :(得分:3)
由于你已经使用了numpy,我会避免在这里使用像
这样的例外def feetToMeters(val):
if numpy.isscalar(val):
return val * 0.3084
else:
return numpy.array(val) * 0.3048
答案 2 :(得分:1)
捕获TypeError很危险,因为它可能是由列表以外的很多东西引起的。我通常会为此目的使用isinstance(val,list)。
答案 3 :(得分:0)
诀窍是你正在尝试支持标量和序列 - 也许这样的东西对你有用:
def feetToMeters(val):
try:
return type(val)(val * 0.3048)
except TypeError:
return type(val)(v*0.3048 for v in val)