繁体   English   中英

如何正确使用 python 的 isinstance() 来检查变量是否为数字?

[英]How to properly use python's isinstance() to check if a variable is a number?

我发现一些旧的 Python 代码正在做类似的事情:

if type(var) is type(1):
   ...

正如预期的那样, pep8抱怨isinstance()的这种推荐用法。

现在,问题是在 Python 2.6 中添加了numbers模块,我需要编写适用于 Python 2.5+ 的代码

所以if isinstance(var, Numbers.number)不是解决方案。

在这种情况下哪个是正确的解决方案?

在 Python 2 中,您可以使用types模块

>>> import types
>>> var = 1
>>> NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
>>> isinstance(var, NumberTypes)
True

请注意使用元组来测试多种类型。

IntTypeIntType只是int等的别名:

>>> isinstance(var, (int, long, float, complex))
True

complex类型要求您的 Python 编译时支持复数; 如果您想为此保护,请使用 try/except 块:

>>> try:
...     NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
... except AttributeError:
...     # No support for complex numbers compiled
...     NumberTypes = (types.IntType, types.LongType, types.FloatType)
...

或者如果您只是直接使用类型:

>>> try:
...     NumberTypes = (int, long, float, complex)
... except NameError:
...     # No support for complex numbers compiled
...     NumberTypes = (int, long, float)
...

在 Python 3 中types不再有任何标准类型别名, complex总是被启用并且不再有longint区别,所以在 Python 3 中总是使用:

NumberTypes = (int, float, complex)

最后但并非最不重要的是,您可以使用numbers.Numbers抽象基类型(Python 2.6 中的新增功能)来支持不直接从上述类型派生的自定义数字类型:

>>> import numbers
>>> isinstance(var, numbers.Number)
True

此检查还为decimal.Decimal()fractions.Fraction()对象返回True

该模块确实假设启用了complex类型; 如果不是,您将收到导入错误。

Python 2 支持四种类型的数字intfloatlongcomplexpython 3.x支持 3 种类型: intfloatcomplex

>>> num = 10
>>> if isinstance(num, (int, float, long, complex)): #use tuple if checking against multiple types
      print('yes it is a number')

yes it is a number
>>> isinstance(num, float)   
False
>>> isinstance(num, int)
True
>>> a = complex(1, 2)
>>> isinstance(a, complex)
True

根据您在鸭子类型中使用的内容,这可能是一种更好的方法( 当然通常推荐使用)。 Martijn Pieters 方法的问题在于,您总是会从列表中遗漏某些类型的数字。 在我的脑海中,您的代码无法使用:有理数,任意精度整数和复数的任何实现。

一种替代方法是编写这样的函数:

def is_number(thing):
    try:
        thing + 1
        return True
    except TypeError:
        return False

此代码应该适用于任何合理的数字实现。 当然有一个主要的缺点:它也适用于大量非数字的不合理实现(即,如果加号运算符重载并接受整数)。

另一种选择(取决于您为什么需要知道某个东西是否是数字)是假设它是一个数字,如果不是,则代码中需要数字的任何位都会抛出错误。

我并不是说这些方法总是更好(不像某些人......)只是它们值得考虑。

可以使用Python 标准库中的数字模块:

# import numbers
isinstance(var, numbers.Number)

告诉var是否是一个数字。 例子:

import numbers
var = 5  ; print(isinstance(var, numbers.Number)) # True
var = 5.5; print(isinstance(var, numbers.Number)) # True
var = 'a'; print(isinstance(var, numbers.Number)) # False

import numpy as np
var = np.float128(888); print(isinstance(var, numbers.Number)) # True

class C: pass; var = C(); print(isinstance(c, numbers.Number)) # False

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM