为什么我无法在Python中扩展bool?

41 投票
6 回答
10809 浏览
提问于 2025-04-15 18:42
>>> class BOOL(bool):
...     print "why?"
... 
why?
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    type 'bool' is not an acceptable base type

我一直以为Python是信任程序员的。

6 个回答

12

因为提问者在评论中提到:

我希望 1 和 2 返回我的类的一个实例。

我觉得有必要指出,这完全是不可能的:Python 不允许你 修改 内置类型(特别是它们的特殊方法)。字面上的 1 永远是内置类型 int 的一个实例,而且无论如何,and 运算符的基本语义是无法被覆盖的 -- a and b 对于任何 ab 来说,总是 等同于 b if a else a(这里没有涉及到 bool 的强制转换,尽管提问者似乎错误地认为发生了这种情况)。

重申这个关键点:a and b 的值 总是、不可改变ab -- 没有 任何 方法可以打破这个语义限制(即使 ab 是你自己定义的特殊类的实例 -- 更不用说它们被限制为 Python 的内置 int 的实例了!)。

12

如果你在使用Python 3,并且想要创建一个可以被当作布尔值(真或假)来判断的类,同时这个类还需要有其他功能,那么你可以在你的类里实现一个叫做 __bool__ 的方法。

在Python 2中,你可以通过实现 __nonzero__ 方法,或者如果你的类是一个容器的话,还可以实现 __len__ 方法,来达到同样的效果。

61

Guido的看法:

我昨晚思考了这个问题,意识到其实不应该允许对布尔值(bool)进行子类化!子类只有在有实例的时候才有用,但如果有一个布尔值的子类实例存在,就会破坏布尔值只有True和False这两个实例的规则!(C类的子类实例也是C类的一个实例。) 我认为不应该提供一个后门来创建额外的布尔值实例,所以我觉得布尔值不应该可以被子类化。

参考链接: http://mail.python.org/pipermail/python-dev/2002-March/020822.html

撰写回答