检查变量是否为整数

1136

如何检查一个变量是否为整数?


3
你好,@Hulk的话似乎让你认为type是解决这个问题的正确方式,但这(几乎肯定)不是正确的方式。 - Katriel
2
@ Hulk:没有冒犯之意。但需要明确的是,我所知道的唯一捕获异常的方法是使用 except 子句。我建议你捕获 TypeError 异常。 - Jungle Hunter
17
这个问题存在歧义,因此答案也被分成了不同的部分。一些人回答如何检查变量的类型(例如,5→True,5.0→False),而另一些人回答如何检查值是否为整数(例如,5→True,5.0→True,Fraction(5,1)→True,5.4→False)。也许应该相应地将问题和答案拆分开来? - endolith
1
最简单的方法(适用于Python 2.7.11)是int(var)== var。适用于.0浮点数,返回布尔值。 - oisinvg
2
你是指“如何确定变量的类型是整数?”还是“如何确定变量的值是整数?” - Benice
显示剩余7条评论
41个回答

1381

如果你需要这样做,那么就这样做

isinstance(<var>, int)

除非你使用的是 Python 2.x,否则你需要

isinstance(<var>, (int, long))

不要使用 type。在Python中,它几乎从不是正确答案,因为它阻碍了多态性的所有灵活性。例如,如果你子类化 int,你的新类应该注册为一个 int,而 type 不会这样做:

class Spam(int): pass
x = Spam(0)
type(x) == int # False
isinstance(x, int) # True

这遵循了Python的强多态性原则:应该接受任何表现得像是一个int的对象,而不是强制要求它是一个。

但是

然而,经典的Python理念是“宁愿请求宽恕,不要事先获得许可”。换句话说,不要检查x是否是整数;假设它是,并且如果它不是,则捕获异常结果:

try:
    x += 1
except TypeError:
    ...

使用抽象基类逐渐取代了这种思维方式,抽象基类可以让你通过让对象继承一个特别构建的类来注册对象应该具有的属性(例如添加?乘法?倍增?)。这是最好的解决方案,因为它将允许仅具有必要和充分属性的对象,但您需要阅读文档以了解如何使用。


8
嗯,我在想关于“但是”部分的意思!在Python中,对方法输入(例如,在使用变量之前)进行适当和清晰的数据检查是否是良好的编程实践,就像在任何编程语言中一样。比如,在想要通过id获取对象时,在将数据提供给数据库查询之前,我会先检查输入是否为整数并且可用,然后再将其交给数据库层处理。 - Henning
3
我相信"Pythonic"的答案应该是"不需要". 通过鸭子类型(duck typing), 只有在引起数据库层面错误时才会出现问题,而根据类型无法判断是否会发生这种情况。因此根据BUT部分的说法,最好的方法是只需让数据库层抛出错误,并在遇到问题时进行处理。任何具有兼容行为的内容都可以使用;int/long问题就是一个很好的例子;如果有人有自定义的 short 类型呢?它与 int 和数据库兼容,但如果检查类型,则您的代码将无法接受它。 - jpmc26
6
虽然这可能听起来很愚蠢,但您能解释一下为什么isinstance(True, int)返回True吗? - Nagri
7
因为Python中的布尔值(True,False)是int的子类 =),这是Python的设计决定。这意味着布尔值就像整数一样,并且任何对象都可以作为布尔值进行评估。 - Katriel
2
@DrBailey也可以只做“x + 42”,不需要赋值。这仍然是有效的Python代码,且不会修改任何内容。 - Kasapo
显示剩余9条评论

167
以下是提到的不同方法的概要:
  • int(x) == x
  • try x = operator.index(x)
  • isinstance(x, int)
  • isinstance(x, numbers.Integral)
以下是如何将它们应用于具有整数值的各种数字类型:

Python 数字类型是否为整数的检查方法表格

你可以看到它们并不完全一致。 分数和有理数在概念上是相同的,但一个提供了.index() 方法而另一个没有。 即使实部为整数且虚部为0,复数类型也不喜欢转换为整数。
np.int8|16|32|64(5)表示np.int8(5)np.int32(5)等都表现出相同的行为)

你的sympy.Rational测试并没有达到你的预期,因为sympy.Rational(5)的计算结果实际上是sympy.Integer的实例。任何会生成整数值的有理数的运算最终都会产生整数。 - user2357112
@user2357112 这不就是我在想什么吗? - endolith
你说sympy.Rational支持operator.index,但实际上并不支持。情况是这样的,sympy会主动切换到更具体的类型。sympy.Rational(5)并不真正适用于表格中“有理数”一节。 - user2357112
@user2357112 但是 Rational(5) 甚至不存在。它会立即转换为 Integer,而 Integer 支持 operator.index - endolith
@user2357112,我的回答传达的信息与现实有何不同之处?Rational(3, 5)不支持.__index__(),但是sympy.Rational(5).__index__()会产生5,因为它立即转换为一个Integer - endolith
显示剩余3条评论

153

到目前为止,所有提出的答案似乎都忽略了一个事实,即双精度浮点数(在Python中,浮点数实际上是双精度浮点数)也可以是整数(如果小数点后没有任何内容)。我使用内置的is_integer()方法来检查这一点。

示例(在for循环中每隔x次执行某些操作):

for index in range(y): 
    # do something
    if (index/x.).is_integer():
        # do something special

编辑:

在调用此方法之前,您始终可以将值转换为浮点数。这三种可能性:

>>> float(5).is_integer()
True
>>> float(5.1).is_integer()
False
>>> float(5.0).is_integer()
True
否则,您可以像Agostino所说的那样首先检查它是否为int:
def is_int(val):
    if type(val) == int:
        return True
    else:
        if val.is_integer():
            return True
        else:
            return False

2
你有这个 is_integer 函数的文档链接吗?我找不到。 - Gabe
4
这里没有太多内容,但这是官方文档:http://docs.python.org/2/library/stdtypes.html#float.is_integer - saroele
5
知道这一点很好。但是,它是一个 float 方法,因此它不是一个通用函数,不能应用于任何类型以确定它是否为整数。 - Craig McQueen
3
首先检查它是否为int(或long),然后检查它是否为float,如果是,则检查is_integer()是否为真。请注意,在Python 3中没有long类型。 - Agostino
6
int(x) == x 也适用于浮点数。 - endolith
显示剩余3条评论

70

如果你真的需要进行检查,最好使用抽象基类而不是具体类。对于整数来说,这意味着:

>>> import numbers
>>> isinstance(3, numbers.Integral)
True

这并不仅限于检查 int,或者只检查 intlong,而是允许其他行为类似于整数的用户定义类型正常工作。


3
isinstance(Fraction(5,1), numbers.Integral) → False. 这个说法正确吗? 这句话在英文中已经非常清晰明了,我的翻译如下:isinstance(Fraction(5,1), numbers.Integral) → False. 这句话正确吗? - endolith
6
我的答案(以及其他答案)都表明变量的类型是否为整数,而不是变量本身是否可以转换为整数而不会丢失信息。因此,是的,您的示例是“False”,就像检查“5.00”的“整数性”一样是“False”。 - Scott Griffiths
3
可以进行一个“这个对象是否可以精确表示为整数”的测试,类似于 type(f)(int(f)) == f,但我认为你也可以这样做。 - Scott Griffiths
2
@martineau:但是这种方法无法获取用户定义的整数类型,这就是使用抽象基类的重点。测试特定数字肯定是一种hack - 显而易见的是,您选择的数字在64位Python 2.x中不起作用。 - Scott Griffiths
1
@martineau:但是类型可能不是int的子类,它可能只表示整数。一个例子就是numpy的int16类型。现在可以承认这也没有使用ABC,但如果它想说它是一个整数类型的对象,但又不想实际上成为int,那么它可以使用ABC。哦,等到他们制作出128位的Python版本再说吧 :) - Scott Griffiths
显示剩余7条评论

40
>>> isinstance(3, int)
True

更多信息请参见此处

请注意,如果您正在寻找类似于int的属性,则此方法不适用。在这种情况下,您可能还需要检查long

>>> isinstance(3L, (long, int))
True

我在Python源代码中看到过对数组/索引类型进行此类检查,但我认为这在C之外不可见。

Token SO回复:您确定应该检查其类型吗?要么不要传递您无法处理的类型,要么不要尝试超越您的潜在代码重用者,他们可能有充分的理由不将int传递给您的函数。


1
我在字典中有一个变量,因此必须在这种情况下进行类型检查。 - Hulk
2
@Hulk:为什么那个案例很特别? - Katriel
3
如果变量的值不是整数,则不再进行进一步处理。最好通过将循环置于异常处理程序中来解决此问题。这不需要进行任何类型检查。 - S.Lott
当然,你应该检查它的类型(通过isinstance或异常处理)。是的,用户可能有充分的理由这样做。但他也可能有不好的理由这样做(或者只是愚蠢,这种情况经常发生),你需要防范这种情况。在完美的世界里,AGE>可以回答“将近五十岁”,但在预算有限的情况下,你可能没有时间实现接近完美的人工智能! - Shayne
1
isinstance(False, int) True - Frutik
显示剩余3条评论

29

为什么不试试这样的东西:

if x%1 == 0: 

9
-1 因为这不是我希望在生产环境或被我的团队成员看到的代码。它掩盖了您的意图。这里的其他大多数答案更加明确,应该被优先选择。 - Dennis
25
@Dennis:但这也适用于小数部分等于零的浮点数。您可以将其封装在一个函数中,这样会更明确。 - Marco Sulla
如果 x 不是一个数字,比如一个字符串会怎么样? - Jason
原始问题不够具体,被解释成两种方式;@Hulk 可以通过询问以下任一问题来消除歧义:“如何确定变量的类型是整数?”或“如何确定变量的值是整数?”投票否定任何一种解释都不是很公平。 - Benice

18

不要过于复杂,为什么不简单化呢?

if type(var) is int:

5
不要使用type(),因为它并不总是有效,应该使用isinstance()代替。请参见上面的答案https://dev59.com/l3A75IYBdhLWcg3wDUco#3501408。 - goetz

14

在这里发现一个相关问题

Python开发者更喜欢不检查类型,而是执行特定于类型的操作并捕获TypeError异常。但是如果您不知道类型,则可以使用以下方法。

>>> i = 12345
>>> type(i)
<type 'int'>
>>> type(i) is int
True

3
你至少应该解释一下为什么不这样做。仅发布这段代码会促进糟糕的Python编程习惯。(虽然它在技术上是正确的,但不应该得到赞同) - Katriel
这就是你想要的。你会高兴地发现它现在也没有被点赞。 - Jungle Hunter
谢谢。取消了踩的操作。(虽然你可以更强调不使用 type =p。) - Katriel

14

我在所有的软件中都使用一个简单的方法。它检查变量是否由数字组成。

test = input("Enter some text here: ")
if test.isdigit() == True:
   print("This is a number.")
else:
   print("This is not a number.")

2
这适用于字符串变量,但对于已经是数字的变量会崩溃(isdigit()是Python中的字符串方法)。 - shacker
另外,isdigit对于负数和浮点数都返回False: '-10'.isdigit()'1.5'.isdigit() - Anton Tarasenko

14

您还可以使用str.isdigit。请尝试查找help(str.isdigit)

def is_digit(str):
      return str.isdigit()

只有当str是字符串时才有效。整数没有isdigit或is_digit方法。 - mcan
3
isdigit() 对于负整数返回 False - Sunny Tambi
1
如果在字符串 x 中没有出现 '.',那么代码会更简单。 - mins

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