多态分派:区分Python整数与浮点数和字符串

时间:2017-03-01 23:53:05

标签: python python-2.7 types python-2.5

假设我有一个需要在其他三个函数之一之间进行调度的函数,具体取决于它是否"类似整数"或者"浮点状"或"字符串式" (或其他):

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等。)

编辑:我也很好奇如何在Python 2.5.3中这样做,因为我坚持使用那个版本的Jython。

2 个答案:

答案 0 :(得分:1)

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

Function forex(audData As Range, euData As Range)
    With WorksheetFunction
        forex = .Average(audData) * .Average(euData)
    End With  
End Function

使用python 2.7和numpy 1.12:

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')

请注意,>>> 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进行测试。

答案 1 :(得分:1)

对于不依赖于明确registernumber ABCs的解决方案(因此它适用于旧的NumPy版本和Python 2.5),您可以使用{{3测试某些东西是否应该表现为整数。 (这是__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')