检查Python对象是否可解释为实数[Python]

3
我用Python写了这个函数:
def is_number_like(x):
     try:
        int(x) + 1
    except:
        return False
    return True

如果我写float(x)或者int(x)是否有区别?在某些情况下,+1部分可能有用吗?

编辑:is_number_like会在传递字符串时返回True - 这不是我想要的。我想要一个函数,在任何时候都会返回False,当文本值作为参数传递时。有这样的方法吗?

也许:

def is_number_like(x):
     try:
        x + 1
    except:
        return False
    return True

会更好吗?

或者可能是:

def is_number_like(x):
     try:
        float(x + 1) == float(x) + 1
    except:
        return False
    return True

我希望编写一个模块,可以接受任何代表一维实数的良好数字类型(例如SimpleITK.sitkUInt8数字类型或numpy.int32等)。

我担心可能会有一些库,在转换为整数或浮点数时不会抛出错误。例如,我可以想象以下情况:

>>> z = SomeComplexType(1. + 2.j)
>>> z
(1+2j)
>>> z -= 2.j
>>> z
(1+0j)
>>> float(z) # does not raise an error
1.

这种情况可能会发生吗?我需要担心吗?

而且,所有设计良好的实数类型都可以无误地转换为float吗?

PS. 我已经阅读了这篇文章:如何检查字符串是否为数字(浮点数)?


2
你尝试过运行 int("1.23") 吗?而且 x 到底应该是什么?一个字符串,还是其他类似数字的对象? - tobias_k
1
我在Python 2.7和3.5中使用float((1+0j))时出现错误(“TypeError: can't convert complex to float”)。 - Scott Hunter
x 应该是一个列表、数组(我想返回 False),或者是 numpy.int(我想让我的函数返回 True)等。 - Śmigło
4个回答

2

float(..)”和“int(..)”之间有区别。

float(..)会尝试解析一个string或任何带有__float__方法的对象。例如,int,float和complex都有__float__方法。您也可以为自定义类定义此类方法。

如果您想将复数转换为float(..),它会产生错误:

>>> float(2+2j)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float

float(..)函数的结果保证是一个float:如果__float__方法返回一个非float值,它将引发TypeError异常:

>>> class Foo:
...     def __float__(self):
...         return 2j
... 
>>> float(Foo())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __float__ returned non-float (type complex)

因此,简单地尝试使用float(..)即可:
def is_number_like(x):
     try:
        float(x)
        return True
    except TypeError, ValueError:
        return False

在Python中,大多数类似数字的类型(如numpy.int16)都支持__float__方法。
另一方面,int(..)str__int__方法一起使用。同样,如果调用int(..),则保证结果是一个int
因此,在中,您可以使用两个检查:一个是float(..),另一个是int(..)
def is_number_like(x):
     try:
        int(x)
        return True
    except TypeError, ValueError:
        try:
            float(x)
            return True
        except TypeError, ValueError:
            return False

如果您想返回类似数字的对象:
def is_number_like(x):
     try:
        return int(x)
    except TypeError:
        try:
            return float(x)
        except TypeError:
            return None

这将返回None,如果两次尝试都失败。
请注意,在中,还有一种long类型(猜猜怎么着,它可以使用__long__)。

1
你应该先尝试将其转换为 int,然后再转换为 float,现在这样什么都不是 int - Ma0
@Ev.Kounis:我不太理解你的评论。你能否请重新表述一下? - Willem Van Onsem
@Ev.Kounis:不,它将返回“True”。这是一个检查它是否类似于数字的对象,而不是将其转换为类似于数字的对象。但是您正确,如果您想要转换它,可以首先尝试使用int。我会修改答案。 - Willem Van Onsem
我后来注意到了返回值,抱歉。但你明白我的意思。 - Ma0
还有float(1+0j)对我来说会引发一个TypeError。你正在运行哪个版本的Python? - Ma0
显示剩余2条评论

2
如果我理解正确,您实际上想知道一个对象是否以“数字”的方式表现(例如,您是否可以将+1附加到它上面)。如果是这样,有一个更简单的方法:
>>> from numbers import Number
>>> 
>>> my_complex_number = 3-2j
>>> my_stringy_number = "3.14"
>>>
>>> isinstance(my_complex_number, Number)
True
>>> isinstance(my_stringy_number, Number)
False

太好了!这很有效,但是我必须排除复数。 - Śmigło
你也可以从numbers库中导入Real,但请注意1.0+0j不是它的实例。 - Marc
如果我使用numbers.Real而不是numbers.Number - 这完全解决了我的问题,谢谢! - Śmigło

1
在Python中,复数不能直接转换为整数或浮点数,否则会引发TypeError: can't convert complex to...错误。
除了“可转换为整数或浮点数”的对象之外的任何其他对象都将引发ValueError
要从自定义类创建一个“可转换”的对象,必须定义适当的“dunders”__int____float__请参阅文档
因此,可以编写一个检查对象是否可以转换为实数的函数:
def is_real_number(number):
    try:
        int(number)
    except TypeError, ValueError:
        return False
    return True

好的,那很明确 - 那字符串呢?我写的另一种方法是否更好用于排除字符串?(请参见我帖子中的编辑) - Śmigło
如果字符串仅包含一个数字,它将被转换;否则它会引发 ValueError。 - lee-pai-long
但我不想将任何字符串转换为数字。有什么建议可以使它通用工作吗? - Śmigło
使用内置函数 isinstance 检查给定对象是否为字符串的实例。(这也适用于字符串子类) - lee-pai-long
实际上,如果您只想检查对象是否为数字,则@Marc给出了最佳答案,即numbers.Number类。 - lee-pai-long

0

为什么不直接使用呢?

any([isinstance(x, t) for t in [float, int, complex]])

您可以修改类型列表以满足您的需求。

有许多类似于数字的对象,比如 numpy.int16,它们并不是 int,但可以被转换为 int - Willem Van Onsem
我想使用用户可以发明的任何类型,例如numpy.float64。我无法枚举所有这些类型。 - Śmigło
@Śmigło:确实,因为您可以在自己的程序中定义类似于数字的类型。 - Willem Van Onsem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接