python使用isinstance比较boolean和int

jak*_*e77 28 python int comparison boolean isinstance

有人可以给我一个解释,为什么isinstance()在下列情况下返回True?编写代码时,我期待False.

print isinstance(True, (float, int))
True
Run Code Online (Sandbox Code Playgroud)

我的猜测是它的python的内部子类,如0和1 - wheter float或int - 在用作布尔值时都会计算,但不知道确切的原因.

什么是解决这种情况的最pythonic方式?我可以使用,type()但在大多数情况下,这被认为是较少pythonic.

use*_*ica 46

由于历史原因,bool是一个子类int,所以True是一个实例int.(最初,Python没有bool类型,返回真值的东西返回1或0. 当它们添加时bool,True和False必须尽可能地为1和0替换为向后兼容,因此子类化. )

"解决"这个问题的正确方法取决于您认为问题的确切原因.

  • 如果你想True停止int,好,太糟糕了.这不会发生.
  • 如果您想检测布尔值并以不同于其他整数的方式处理它们,您可以这样做:

    if isinstance(whatever, bool):
        # special handling
    elif isinstance(whatever, (float, int)):
        # other handling
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果要检测特定类完全相同的对象,float或者int拒绝子类,则可以执行以下操作:

    if type(whatever) in (float, int):
        # Do stuff.
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果你想检测所有浮点数和整数,你就已经这样做了.

  • **更深入的解释第 2 部分:** 您甚至可以执行 `print(True + 3)`,即 `4` (1 + 3),以及 `print(False + 3)`,即 `3` (0 + 3) )。呵呵。但正如上面的答案所述,如果你想 100% 确定它们传递的是 `int` 而不是 `bool`,你只需检查 `if type(param) is int`,因为它不接受任何子类。(如果您的 API 用户可能会传递从“int”派生的自定义对象作为基类,例如,如果他们创建一个带有一些额外方法的“int”数字类...因为他们的子类也会被如此严格的检查拒绝...) (5认同)
  • **更深入的解释:** `True` 和 `False` 是 `int` 类的单例实例... `print(True.real)` 是 `1`,`print(False.real)` 是 ` 0`。`print(True == 1)` 为真,而 `print(False == 0)` 为真。因此,如果您期望参数是 int,并且用户传递的是 bool,那么是的,“isinstance(param, int)”检查对于他们传递的值将“令人烦恼地”为 true,因为 bool 是int...但这有点无害,因为就好像它们传递了“param = 1”或“param = 0”。所以你仍然可以对其进行数字运算,因为布尔值内部是一个“int”。 (4认同)

Vic*_*bot 11

您可以查看方法解析顺序,并从那里找到所有超类:

>>> bool.__mro__
(<class 'bool'>, <class 'int'>, <class 'object'>)
Run Code Online (Sandbox Code Playgroud)


sbz*_*sbz 5

是的,没错,它是 int 的子类,您可以使用解释器进行验证:

>>> int.__subclasses__()
[<type 'bool'>]
Run Code Online (Sandbox Code Playgroud)


Eya*_*vin 5

如果您只想检查int

if type(some_var) is int:
    return True

else:
    return False
Run Code Online (Sandbox Code Playgroud)