使用 isinstance 比较 boolean 和 int

Comparing boolean and int using isinstance

谁能给我解释一下为什么 isinstance() returns 在以下情况下为真?我在编写代码时预计会出现 False。

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

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

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

由于历史原因,boolint 的子 class,因此 Trueint 的实例。 (本来Python没有bool类型,返回真值的东西返回1或0。When they added bool,True和False必须尽可能的替代1和0,以备后退兼容性,因此 subclassing.)

"solve" 的正确方法取决于您对问题的看法。

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

    if isinstance(whatever, bool):
        # special handling
    elif isinstance(whatever, (float, int)):
        # other handling
    
  • 如果你想检测具体class正好是floatint的对象,拒绝subclasses,你可以这样做:

    if type(whatever) in (float, int):
        # Do stuff.
    
  • 如果您想检测所有浮点数和整数,您已经在这样做了。

对,没错,是int的子类,可以用解释器验证:

>>> int.__subclasses__()
[<type 'bool'>]

如果您只想检查 int:

if type(some_var) is int:
    return True

else:
    return False

查看 python 在 bool 和 int

上的一些行为(不是很奇怪)
>>> 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;

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

>>> bool.__mro__
(<class 'bool'>, <class 'int'>, <class 'object'>)

这是一个实例检查器,它使用 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