有人能解释一下为什么在下面的情况下 isinstance()
返回 True 吗?当我编写代码时,我期望的是 False。
print isinstance(True, (float, int))
True
我猜可能是Python的内部子类化,因为无论是float还是int的零和一在用作布尔值时都会被评估,但不知道确切的原因。
解决这种情况最pythonic的方法是什么?我可以使用type()
,但在大多数情况下,这被认为不够pythonic。
有人能解释一下为什么在下面的情况下 isinstance()
返回 True 吗?当我编写代码时,我期望的是 False。
print isinstance(True, (float, int))
True
我猜可能是Python的内部子类化,因为无论是float还是int的零和一在用作布尔值时都会被评估,但不知道确切的原因。
解决这种情况最pythonic的方法是什么?我可以使用type()
,但在大多数情况下,这被认为不够pythonic。
bool
是int
的子类,因此True
是int
的一个实例。(最初,Python没有bool类型,返回真值的东西返回1或0。当他们添加了bool
时,为了向后兼容尽可能地替换1和0,True和False必须成为插入式替换,因此进行了子类化。)True
to stop being an int
, well, too bad. That's not going to happen.If you want to detect booleans and handle them differently from other ints, you can do that:
if isinstance(whatever, bool):
# special handling
elif isinstance(whatever, (float, int)):
# other handling
If you want to detect objects whose specific class is exactly float
or int
, rejecting subclasses, you can do that:
if type(whatever) in (float, int):
# Do stuff.
您可以查看方法解析顺序,并从中找到所有的超类:
>>> bool.__mro__
(<class 'bool'>, <class 'int'>, <class 'object'>)
是的,没错,它是 int 的子类,您可以使用解释器进行验证:
>>> int.__subclasses__()
[<type 'bool'>]
int
:if type(some_var) is int:
return True
else:
return False
return isinstance(some_var, int)
- wjandrea了解一些关于 Python 中布尔值和整数的行为(并不那么奇怪)
>>> 1 == True
True
>>> 0 == False
True
>>> True*5 == 0
False
>>> True*5 == 5
True
>>>
它们可以互换使用到什么程度...!
从 boolobject.h(win py 2.7)中,我可以看到将 int 定义为 bool obj 的 typedef。因此,很明显 bool 继承了 int 的一些面部特征。
#ifndef Py_BOOLOBJECT_H
#define Py_BOOLOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef PyIntObject PyBoolObject;
这里有一个实例检查器,它对布尔型数据是安全的,而且可以像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
print(True.real)
是1,而print(False.real)
是0。print(True == 1)
为真,并且print(False == 0)
也为真。所以如果你希望参数是整数类型,但用户却传入了布尔类型,那么一个isinstance(param, int)
的检查将会“恼人地”对他们传递的值返回真,因为布尔型本质上是一种整数类型...但这不会有太大的影响,因为它就像是传递了param = 1
或者param = 0
。因此,您仍然可以对其进行数值运算,因为布尔值在内部实际上是一种“整数”类型。 - Mitch McMabersprint(True + 3)
,它会输出4
(1 + 3),以及print(False + 3)
,它会输出3
(0 + 3)。呵呵。但是正如上面的答案所指出的那样,如果你想要100%确定参数是一个int
而不是一个bool
,你只需要检查if type(param) is int
,因为这不会接受任何子类。(只要注意一下,如果你的API用户可能会传递他们自己从int
派生的自定义对象作为基类,例如如果他们制作了一个带有一些额外方法的数字类,该类是一个int
...那么他们的子类也将被这样严格的检查拒绝...) - Mitch McMabers