在Python中有没有合法使用list ,list ?
由于True
和False
是int
实例,所以在Python中以下是有效的:
>>> l = [0, 1, 2] >>> l[False] 0 >>> l[True] 1
我明白为什么会这样。 但是,我发现这种行为有点意外,并可能导致难以debugging的错误。 它肯定咬了我几次。
任何人都可以想到合理使用索引列表True
或False
?
过去有人用这种行为来产生一个穷人的条件expression式 :
['foo', 'bar'][eggs > 5] # produces 'bar' when eggs is 6 or higher, 'foo' otherwise
但是,在Python 2.5中添加了一个适当的条件expression式 ,这是非常令人不悦的,因为你说的理由:依赖于布尔types是整数的一个子类对于维护者来说太“神奇”和不可读。
所以,除非你是代码打高尔夫球( 故意产生非常紧凑和晦涩的代码),使用
'bar' if eggs > 5 else 'foo'
相反,它具有额外的优点,这两个expression式之间的select是懒惰评估; 如果eggs > 5
为false,则if
之前的expression式不会执行。
如果你不明白为什么bool
是一个有效的索引参数:这只是为了与bool
是int
的子类的事实保持一致 ,在Python中它是一个数字types。
如果你问为什么bool
是一个数字types,那么你必须明白,在旧的Python版本中并不存在bool
,而是使用int
s来代替。
我会添加一些历史性的论点。 首先在python中添加bool
的方法很快就在Guido van Rossum(又名BDFL)blogpost: Python的历史: bool
, True
和False
的历史中描述过 。 该types是通过PEP 285添加的。
PEP包含了用于这个决定的实际理由。 我将引用下面的PEP的一些部分。
4)我们是否应该努力通过适当的警告消除bools上的非布尔操作,例如
True+1
最终(在Python 3000中)是非法的?=>否。
有一个小的声音less数派喜欢看到“教科书”bools根本不支持算术运算,但大多数评论家赞同我bools应该总是允许算术运算。
6)应该
bool
从int
inheritance?=>是的。
在理想的世界里,
bool
可能会更好地实现为一个单独的整数types,知道如何执行混合模式算术。 但是, 从int
inheritancebool
可以大大简化实现(部分原因是调用PyInt_Check()
所有C代码都将继续工作 – 这将为int
子类返回true)。 另外,我相信在可替代性方面这是正确的:需要一个int
代码可以被提供一个bool
,它将performance为0
或1
。 需要bool
代码在给定int
时可能不起作用; 例如,3&4是0,但当被视为真值时,3和4都是真的。
因为
bool
从int
inheritance,True+1
是有效的,等于2
,依此类推。 这对于向后兼容很重要 :因为比较等当前返回整数值,所以没有办法告诉现有应用程序使用这些值。
由于向后兼容 ,booltypes缺less许多属性,有些人希望看到。 例如,允许使用一个或两个bool参数的算术运算,将False视为0,将True视为1.另外,bool可以用作序列索引。
我不认为这是一个问题,我也不想在这个方向上发展语言。 我不认为对“布尔性”的更严格的解释会使语言更加清晰。
总结 :
- 向后兼容性:有很多代码已经使用
int
s0
和1
来表示False
和True
并且它们中的一些在数值计算中使用了这些值。 - 拥有“非教科书”
bool
types并不是什么大事 - Python社区中有很多人想要这些function
- BDFL这样说。
通常有更好的方法,但是布尔指数有其用途。 当我想把一个布尔结果转换成更具人类可读性的东西时,我已经使用了它们:
test_result = run_test() log.info("The test %s." % ('Failed', 'Passed')[test_result])