如何正确合并duck-typing以返回原始类型?

car*_*ism 8 python duck-typing numpy

我真的希望这不是重复.我试图搜索我的问题,我似乎无法找到它.

所以我有一个相当简单的功能,可以将脚转换为米:

def feetToMeters(val):
    return numpy.array(val) * 0.3048
Run Code Online (Sandbox Code Playgroud)

这很好用,并接受整数,浮点数,数组和列表.但是,如果我放入一个列表(而不是一个numpy数组),我想要返回一个列表.所以我写了这个:

def feetToMeters(val):
    try:
        return val * 0.3084
    except TypeError:
        return [0.3084 * v for v in val]
Run Code Online (Sandbox Code Playgroud)

(或者return list(numpy.array(val) * 0.3084),如果我想在numpy这里使用,我可以使用最后一行,我不知道这是否真的很重要.)

这是在这里加入duck-typing的最佳方法,这样我就可以避免使用这个type函数了吗?最初我试过AttributeError,但它没有用.尽管如此,我仍然感到厌倦TypeError.

if type(val) is list反而使用是否是亵渎神明的?

Fre*_*Foo 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
Run Code Online (Sandbox Code Playgroud)

注意:

  • 传递子类的实例list将导致list返回plain ;
  • 传递列表列表将导致返回NumPy数组列表.

您可以对此进行扩展以特别处理更多类型,但通常,对于要处理的每种类型,您需要编写更多代码,因为您需要知道如何构造该类型.因此,这种类型转换通常留给客户端代码.