我发现了一些旧代的Python代码:
if type(var) is type(1):
...
正如预期的那样,pep8
抱怨推荐使用isinstance()
。
现在,问题是在Python 2.6中添加了numbers
模块,我需要编写适用于Python 2.5 +的代码
所以if isinstance(var, Numbers.number)
不是解决方案。
在这种情况下哪个是正确的解决方案?
答案 0 :(得分:98)
在Python 2中,您可以使用types
module:
>>> import types
>>> var = 1
>>> NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
>>> isinstance(var, NumberTypes)
True
注意使用元组来测试多种类型。
在幕后,IntType
只是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
始终处于启用状态且不再存在long
vs int
差异,因此在Python 3中总是使用:
NumberTypes = (int, float, complex)
最后但并非最不重要的是,您可以使用numbers.Numbers
abstract base type(Python 2.6中的新增功能)来支持不直接从上述类型派生的自定义数字类型:
>>> import numbers
>>> isinstance(var, numbers.Number)
True
此检查还会返回True
和decimal.Decimal()
个对象的fractions.Fraction()
。
该模块确实假设complex
类型已启用;如果不是,你会得到导入错误。
答案 1 :(得分:18)
Python 2支持四种类型的数字int
,float
,long
和complex
以及python 3.x
支持3:int
,{{ 1}}和float
complex
答案 2 :(得分:3)
取决于您在duck typing中使用的内容,这可能是一种更好的方法(certainly commonly recommended)。 Martijn Pieters的方法存在的问题是你总会错过列表中的某些类型的数字。在我的头脑中,你的代码将无法使用:sympy有理数,任意精度整数和任何复数的实现。
另一种方法是编写这样的函数:
def is_number(thing):
try:
thing + 1
return True
except TypeError:
return False
此代码应与数字的任何合理实现一起使用。当然有一个主要的缺点:它也会使用大量非数字的不合理实现(即如果加号运算符被重载并接受整数)。
另一种选择(取决于你需要知道某些东西是否为数字的原因)只是假设它是一个数字,如果不是错误,那么代码中的任何一位都需要一个数字。
我不是说这些方法总是更好(不像有些人......)只是他们值得考虑。