为啥我不能在 Python 中扩展 bool?

Posted

技术标签:

【中文标题】为啥我不能在 Python 中扩展 bool?【英文标题】:Why I can't extend bool in Python?为什么我不能在 Python 中扩展 bool? 【发布时间】:2011-01-11 10:42:52 【问题描述】:
>>> 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 信任程序员。

【问题讨论】:

是否要添加 FileNotFound 值? Google 搜索或 SO 搜索“组合与继承”可能在这里有用。 【参考方案1】:

如果您使用的是 Python 3,并且您希望有一个可以作为布尔值评估但还包含其他功能的类,请在您的类中实现 __bool__

在 Python 2 中,可以通过实现 __nonzero____len__(如果您的类是容器)来实现相同的效果。

【讨论】:

在 Python 2.x 中,您可以通过实现 __nonzero____len__ 来做同样的事情。 我希望 1 和 2 返回我的类的一个实例。你会怎么做? 第一个子类化 bool,然后覆盖 int 方法...为什么不从头开始创建自己的类?【参考方案2】:

由于 OP 在评论中提到:

我希望1 and 2 返回一个实例 我班的。

我认为重要的是要指出这是完全不可能的:Python 不允许您更改 内置类型(尤其是它们的特殊方法)。文字 1 将始终是内置类型 int 的实例,并且在任何情况下,and 运算符的基本语义无论如何都不能被覆盖——a and b 总是相同b if a else a for any ab (不涉及 bool 强制,即使 OP 似乎错误地认为正在发生)。

重申这个关键点:a and b 的值是永远不变ab - 没有没有 方法可以打破这种语义约束(即使 ab 是您自己的特殊类的实例——当然,当它们被限制为 Python 的内置 int 的实例时更是如此!-)。

【讨论】:

不可能改变内置类型?这不是forbiddenfruit library 所做的吗?【参考方案3】:

这里有一篇文章解释了这个决定背后的原因:http://mail.python.org/pipermail/python-dev/2004-February/042537.html

这个想法是 bool 有一个特定的目的 - 成为 True 或成为 False,添加它只会使您的代码在其他地方复杂化。

【讨论】:

【参考方案4】:

Guido 对此的看法:

我最后想到了这个 晚上,并意识到你不应该 完全可以继承 bool !一种 子类只有在它有用时才有用 有实例,但仅仅是存在 bool 子类的实例 会打破 True 的不变量 和 False 是唯一的实例 布尔! (C 的子类的一个实例 也是 C 的一个实例。)我认为 重要的是不要提供 后门创建额外的布尔 实例,所以我认为 bool 不应该 可以子类化。

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

【讨论】:

True 和 False 是单例的。这是一个更好的答案。 很高兴知道事情是一致的:class Foo(None.__class__): ... -> TypeError: type 'NoneType' is not an acceptable base type 试图理解这个答案:从bool 继承不会以任何方式影响TrueFalse 的不变性。子类的一个实例仍然是TrueFalse(从bool 的角度来看)。如果您覆盖__eq__(),它可能具有其他属性,并且可能等于或不等于其中之一,否则它不会对bool或其两个可能值产生负面影响。我错过了什么? @user3204459 在测试TrueFalseNone 之类的值时,我们可以使用标识操作is,因为我们知道这些值是单例的。许多代码已经依赖于这个技巧,因此对这些类型进行子类化会破坏这些基于身份的检查。 @flakes 抱歉,我还是不明白。 TrueFalse 仍将是 bool,并且只会在使用 is 时针对 TrueFalse 进行测试。所以呢?什么被打破了?你能举个具体的例子吗?为什么False 是单例的,而0 不是?【参考方案5】:

因为bool 应该只有两个值——TrueFalse。如果你能够继承bool,你可以为它定义任意数量的值,这绝对不是你想要的。

一个更好的问题是:为什么要扩展 bool?

【讨论】:

我想添加一个属性,让我可以跟踪对象上的一些东西。 @Juanjo 那么你想要的不是布尔值,它是一个布尔值和其他东西的元组。布尔值必须是 True 或 False,没有其他值和其他属性会使该类的实例与 True 和 False 进行否定比较。这将发生,它不再是布尔值。 好的,但是我不能覆盖 int.__nonzero__ 来返回这个元组。我可以吗? 答案:模糊逻辑、bool中的运算符重载等 重载魔法方法并添加额外的方法,同时保持布尔运算的一致性。即,使用几个 mixin 来获得一个布尔类,该类可以很容易地转换为 ctypes 和字符串转换为/从字符串,其方式符合 C 自定义网络协议 API。

以上是关于为啥我不能在 Python 中扩展 bool?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能从我的 python 脚本创建可执行文件?

为啥我不能在 main.py 中使用 kivy 添加图像?

为啥我不能直接将 int 或 bool 传递给 OCMock 的“andReturnValue”参数?

python3在pycharm中为啥导入random模块不能用? TypeError: 'module' object is not callable

为啥我不能将任意迭代分配给步长为 -1 的扩展切片?

为啥python的保存类型是Pythinfiles