【问题标题】:polymorphic dispatch: distinguishing Python integers vs. floating-point numbers vs. strings多态调度:区分 Python 整数、浮点数和字符串
【发布时间】:2017-07-21 12:38:51
【问题描述】:

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

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。

【问题讨论】:

  • 也许here 可以满足您的需求?

标签: python python-2.7 types python-2.5


【解决方案1】:

对于不依赖于 registernumber ABC 的类的解决方案(因此它适用于旧 NumPy 版本和 Python 2.5),您可以使用 operator.index 来测试是否有应该表现为整数。 (这是__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')

【讨论】:

  • 太棒了! operator.index 如何“知道” numpy 整数?
  • @JasonS:他们实现了__index__ 方法。
  • 哦。呃,明白了。谢谢!这对我帮助很大。
【解决方案2】:

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

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 进行测试。

【讨论】:

  • isinstance(np.int32(1), numbers.Integral) -> False
  • 哦,太好了!我尝试查看np.float64 的基类,但不知何故我只能找到object。看起来isinstance(np.float64(123.456), numbers.Real) 返回True
  • 哦,@MosesKoledoye 找到了一个反例。德拉特。 :-(
  • @MosesKoledoye 我无法在 Python 3.5 上重现它
  • 在python 2.7(问题已标记)和最新的numpy(1.12)上,isinstance(np.int32(1), numbers.Integral) -> True
猜你喜欢
  • 1970-01-01
  • 2013-02-27
  • 1970-01-01
  • 2015-07-18
  • 2020-05-25
  • 1970-01-01
  • 1970-01-01
  • 2022-10-16
  • 1970-01-01
相关资源
最近更新 更多