多态分派:区分Python整数与floatingpoint数字与字符串

2024-10-06 11:50:01 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个函数需要在其他三个函数中的一个函数之间分派,这取决于它是“类似整数”还是“类似浮点”或“类似字符串”(或其他类型):

def handleThing(x):
   if is_integer_like(x):
      return handleInteger(x)
   if is_floating_point_like(x):
      return handleFloatingPoint(x)
   if isinstance(x, basestring):
      return handleString(x)
   raise ValueError('handleThing only handles numbers and strings')

如何编写is_integer_likeis_floating_point_like来处理以下类型,而不需要使用numpy库?我正在寻找一些像鸭子打字,但被难住了,因为似乎没有一个共同的方法,使我能够区分他们。你知道吗

当我做同样的事情来确定某个东西是否是映射类型时,除了isinstance(x, collections.Mapping)之外,我通常会做如下事情

def ismapping(x):
   return hasattr(x, 'iteritems')

我需要处理:

  • 类整数类型:

    • int
    • long
    • 所有numpy整数类型(np.intnp.int32np.uint32等)
  • 类浮点类型:

    • float
    • complex
    • 所有numpy浮点类型(np.float32np.float64等)

编辑:我也很好奇如何在Python2.5.3中做到这一点,因为我一直在使用Jython的那个版本。你知道吗


Tags: 函数numpy类型returnifisdefnp
2条回答

对于一个不依赖类显式地register使用numberabc进行自身操作的解决方案(因此它可以在旧的NumPy版本和python2.5上工作),您可以使用^{}来测试某个对象是否应该作为整数。(这是一个围绕__index__的包装器,您可以实现它,使对象可用作列表索引。)

def handleThing(x):
    try:
        operator.index(x)
    except TypeError:
        pass
    else:
        return handleInteger(x)

    if isinstance(x, basestring):
        return handleString(x)

    try:
        # Would give false positive for strings, but we handled those already.
        float(x)
    except TypeError:
        pass
    else:
        return handleFloatingPoint(x)

    # You might want TypeError here.
    raise ValueError('handleThing only handles numbers and strings')

检查它是否实现了适当的抽象基类:

def handleThing(x):
   import numbers
   if isinstance(x, numbers.Integral):
      return handleInteger(x)
   elif isinstance(x, numbers.Real):
      return handleFloatingPoint(x)
   elif isinstance(x, basestring):
      return handleString(x)
   raise ValueError('handleThing only handles numbers and strings')

使用python 2.7和numpy 1.12:

>>> all([isinstance(t(1.0), numbers.Integral) for t in (np.int, np.int32, np.uint32, np.int64, numpy.uint64)])
True

>>> all([isinstance(t(1.0), numbers.Real) for t in (float, np.float32, np.float64, np.float128)])
True

请注意,complex数字不是实数,您应该用numbers.Complex来测试它。你知道吗

相关问题 更多 >