67

有人可以解释一下为什么isinstance()在以下情况下返回 True 吗?在编写代码时,我期望 False。

print isinstance(True, (float, int))
True

我的猜测是它的 Python 的内部子类化为零和一——无论是浮点数还是整数——都在用作布尔值时进行评估,但不知道确切的原因。

解决这种情况的最pythonic方法是什么?我可以使用type(),但在大多数情况下,这被认为不那么 Pythonic。

4

6 回答 6

100

由于历史原因,bool是 的子类intTrue的实例也是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
    
  • 如果要检测特定类为floator的对象int,拒绝子类,可以这样做:

    if type(whatever) in (float, int):
        # Do stuff.
    
  • 如果你想检测所有的浮点数和整数,你已经在这样做了。
于 2016-06-17T19:02:49.083 回答
7

是的,没错,它是 int 的子类,你可以使用解释器来验证它:

>>> int.__subclasses__()
[<type 'bool'>]
于 2017-06-06T10:51:53.183 回答
5

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

>>> bool.__mro__
(<class 'bool'>, <class 'int'>, <class 'object'>)
于 2020-01-06T12:18:30.147 回答
4

如果您只想检查int

if type(some_var) is int:
    return True

else:
    return False
于 2018-02-18T09:20:38.420 回答
0

这是一个实例检查器,它使用 bool 是安全的,并且采用单一类型或类型元组,就像isinstance()

def isInst(o, of) -> bool:
    if o is None: return False
    cls = o.__class__
    if isinstance(of, type):
        return cls == of

    else:
        if cls == bool:
            return bool in of
        else:
            for i in range(len(of)):
                if cls == of[i]: return True

    return False
于 2021-04-24T02:00:27.457 回答
0

在 bool 和 int 上查看 python 的一些行为(不是那么奇怪)

>>> 1 == True  
True           
>>> 0 == False 
True           
>>> True*5 == 0
False          
>>> True*5 == 5
True           
>>> 

它们可以如何互换使用......!

从 boolobject.h (win py 2.7) 我可以看到 bool obj 的类型定义为 int。所以很明显 bool 继承了 int 的一些面部特征。

#ifndef Py_BOOLOBJECT_H
#define Py_BOOLOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif


typedef PyIntObject PyBoolObject;
于 2019-01-24T06:56:04.747 回答